summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Icq10/icq10.vcxproj2
-rw-r--r--protocols/Icq10/icq_xstatus/CMakeLists.txt (renamed from protocols/IcqOscarJ/icq_xstatus/CMakeLists.txt)0
-rw-r--r--protocols/Icq10/icq_xstatus/res/ICONS.rc (renamed from protocols/IcqOscarJ/icq_xstatus/res/ICONS.rc)264
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus34.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus34.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus35.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus35.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus36.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus36.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus38.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus38.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus39.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus39.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus40.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus40.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus41.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus41.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus42.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus42.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus45.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus45.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus46.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus46.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus47.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus47.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus48.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus48.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus49.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus49.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus50.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus50.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus51.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus51.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus52.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus52.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus53.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus53.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus54.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus54.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus56.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus56.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus57.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus57.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus58.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus58.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus59.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus59.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus60.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus60.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus61.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus61.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus62.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus62.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus63.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus63.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus65.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus65.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus66.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus66.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus67.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus67.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus68.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus68.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus69.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus69.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus70.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus70.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus71.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus71.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus72.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus72.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus73.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus73.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus74.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus74.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus75.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus75.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus76.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus76.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus77.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus77.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus78.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus78.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus79.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus79.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus81.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus81.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus82.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus82.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus83.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus83.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus84.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus84.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/Xstatus86.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/Xstatus86.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus01.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus01.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus02.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus02.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus03.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus03.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus04.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus04.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus05.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus05.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus06.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus06.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus07.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus07.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus08.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus08.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus09.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus09.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus10.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus10.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus11.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus11.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus12.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus12.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus13.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus13.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus14.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus14.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus15.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus15.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus16.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus16.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus17.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus17.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus18.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus18.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus19.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus19.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus20.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus20.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus21.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus21.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus22.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus22.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus23.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus23.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus24.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus24.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus25.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus25.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus26.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus26.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus27.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus27.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus28.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus28.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus29.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus29.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus30.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus30.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus31.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus31.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus32.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus32.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus33.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus33.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus37.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus37.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus43.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus43.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus44.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus44.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus55.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus55.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus64.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus64.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus80.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus80.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/res/xstatus85.ico (renamed from protocols/IcqOscarJ/icq_xstatus/res/xstatus85.ico)bin5430 -> 5430 bytes
-rw-r--r--protocols/Icq10/icq_xstatus/src/resource.h (renamed from protocols/IcqOscarJ/icq_xstatus/src/resource.h)206
-rw-r--r--protocols/Icq10/icq_xstatus/xStatus_ICQ.vcxproj (renamed from protocols/IcqOscarJ/icq_xstatus/xStatus_ICQ.vcxproj)54
-rw-r--r--protocols/IcqOscarJ/CMakeLists.txt6
-rw-r--r--protocols/IcqOscarJ/docs/license.txt340
-rw-r--r--protocols/IcqOscarJ/docs/readme.txt480
-rw-r--r--protocols/IcqOscarJ/icqoscar8.vcxproj28
-rw-r--r--protocols/IcqOscarJ/icqoscar8.vcxproj.filters4
-rw-r--r--protocols/IcqOscarJ/proto_icq/CMakeLists.txt2
-rw-r--r--protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj28
-rw-r--r--protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj.filters4
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/Away.icobin5430 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/DND.icobin5430 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/FFC.icobin5430 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/Invisible.icobin5430 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/NA.icobin5430 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/Occupied.icobin5430 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/Offline.icobin5430 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/Online.icobin5430 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/Phone.icobin5430 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/proto_icq/res/Proto_ICQ.rc77
-rw-r--r--protocols/IcqOscarJ/proto_icq/src/resource.h24
-rw-r--r--protocols/IcqOscarJ/res/expandst.icobin1150 -> 0 bytes
-rw-r--r--protocols/IcqOscarJ/res/resources.rc544
-rw-r--r--protocols/IcqOscarJ/res/version.rc9
-rw-r--r--protocols/IcqOscarJ/src/askauthentication.cpp82
-rw-r--r--protocols/IcqOscarJ/src/capabilities.cpp247
-rw-r--r--protocols/IcqOscarJ/src/capabilities.h43
-rw-r--r--protocols/IcqOscarJ/src/chan_01login.cpp81
-rw-r--r--protocols/IcqOscarJ/src/chan_02data.cpp200
-rw-r--r--protocols/IcqOscarJ/src/chan_03error.cpp31
-rw-r--r--protocols/IcqOscarJ/src/chan_04close.cpp279
-rw-r--r--protocols/IcqOscarJ/src/chan_05ping.cpp59
-rw-r--r--protocols/IcqOscarJ/src/changeinfo.h121
-rw-r--r--protocols/IcqOscarJ/src/channels.h45
-rw-r--r--protocols/IcqOscarJ/src/constants.cpp131
-rw-r--r--protocols/IcqOscarJ/src/cookies.cpp254
-rw-r--r--protocols/IcqOscarJ/src/cookies.h136
-rw-r--r--protocols/IcqOscarJ/src/db.cpp153
-rw-r--r--protocols/IcqOscarJ/src/directpackets.cpp273
-rw-r--r--protocols/IcqOscarJ/src/dlgproc.cpp507
-rw-r--r--protocols/IcqOscarJ/src/editlist.cpp196
-rw-r--r--protocols/IcqOscarJ/src/editstring.cpp336
-rw-r--r--protocols/IcqOscarJ/src/fam_01service.cpp856
-rw-r--r--protocols/IcqOscarJ/src/fam_02location.cpp257
-rw-r--r--protocols/IcqOscarJ/src/fam_03buddy.cpp716
-rw-r--r--protocols/IcqOscarJ/src/fam_04message.cpp2620
-rw-r--r--protocols/IcqOscarJ/src/fam_09bos.cpp91
-rw-r--r--protocols/IcqOscarJ/src/fam_0alookup.cpp118
-rw-r--r--protocols/IcqOscarJ/src/fam_0bstatus.cpp52
-rw-r--r--protocols/IcqOscarJ/src/fam_13servclist.cpp1720
-rw-r--r--protocols/IcqOscarJ/src/fam_15icqserver.cpp1068
-rw-r--r--protocols/IcqOscarJ/src/fam_17signon.cpp161
-rw-r--r--protocols/IcqOscarJ/src/families.h73
-rw-r--r--protocols/IcqOscarJ/src/globals.h59
-rw-r--r--protocols/IcqOscarJ/src/guids.h76
-rw-r--r--protocols/IcqOscarJ/src/i18n.cpp499
-rw-r--r--protocols/IcqOscarJ/src/i18n.h61
-rw-r--r--protocols/IcqOscarJ/src/icq_advsearch.cpp149
-rw-r--r--protocols/IcqOscarJ/src/icq_advsearch.h28
-rw-r--r--protocols/IcqOscarJ/src/icq_avatar.cpp1315
-rw-r--r--protocols/IcqOscarJ/src/icq_avatar.h118
-rw-r--r--protocols/IcqOscarJ/src/icq_clients.cpp1007
-rw-r--r--protocols/IcqOscarJ/src/icq_constants.h645
-rw-r--r--protocols/IcqOscarJ/src/icq_db.cpp207
-rw-r--r--protocols/IcqOscarJ/src/icq_direct.cpp946
-rw-r--r--protocols/IcqOscarJ/src/icq_direct.h87
-rw-r--r--protocols/IcqOscarJ/src/icq_directmsg.cpp313
-rw-r--r--protocols/IcqOscarJ/src/icq_fieldnames.cpp576
-rw-r--r--protocols/IcqOscarJ/src/icq_fieldnames.h48
-rw-r--r--protocols/IcqOscarJ/src/icq_filerequests.cpp191
-rw-r--r--protocols/IcqOscarJ/src/icq_filetransfer.cpp482
-rw-r--r--protocols/IcqOscarJ/src/icq_firstrun.cpp108
-rw-r--r--protocols/IcqOscarJ/src/icq_http.cpp198
-rw-r--r--protocols/IcqOscarJ/src/icq_http.h44
-rw-r--r--protocols/IcqOscarJ/src/icq_infoupdate.cpp333
-rw-r--r--protocols/IcqOscarJ/src/icq_menu.cpp154
-rw-r--r--protocols/IcqOscarJ/src/icq_opts.cpp544
-rw-r--r--protocols/IcqOscarJ/src/icq_packet.cpp895
-rw-r--r--protocols/IcqOscarJ/src/icq_packet.h120
-rw-r--r--protocols/IcqOscarJ/src/icq_popups.cpp279
-rw-r--r--protocols/IcqOscarJ/src/icq_popups.h41
-rw-r--r--protocols/IcqOscarJ/src/icq_proto.cpp1819
-rw-r--r--protocols/IcqOscarJ/src/icq_proto.h902
-rw-r--r--protocols/IcqOscarJ/src/icq_rates.cpp445
-rw-r--r--protocols/IcqOscarJ/src/icq_rates.h148
-rw-r--r--protocols/IcqOscarJ/src/icq_server.cpp403
-rw-r--r--protocols/IcqOscarJ/src/icq_server.h62
-rw-r--r--protocols/IcqOscarJ/src/icq_servlist.cpp2349
-rw-r--r--protocols/IcqOscarJ/src/icq_servlist.h168
-rw-r--r--protocols/IcqOscarJ/src/icq_uploadui.cpp873
-rw-r--r--protocols/IcqOscarJ/src/icq_xstatus.cpp1133
-rw-r--r--protocols/IcqOscarJ/src/icq_xtraz.cpp400
-rw-r--r--protocols/IcqOscarJ/src/icqosc_svcs.cpp679
-rw-r--r--protocols/IcqOscarJ/src/icqosc_svcs.h35
-rw-r--r--protocols/IcqOscarJ/src/init.cpp149
-rw-r--r--protocols/IcqOscarJ/src/log.cpp150
-rw-r--r--protocols/IcqOscarJ/src/log.h34
-rw-r--r--protocols/IcqOscarJ/src/loginpassword.cpp88
-rw-r--r--protocols/IcqOscarJ/src/oscar_filetransfer.cpp2116
-rw-r--r--protocols/IcqOscarJ/src/oscar_filetransfer.h160
-rw-r--r--protocols/IcqOscarJ/src/resource.h168
-rw-r--r--protocols/IcqOscarJ/src/stdafx.cxx18
-rw-r--r--protocols/IcqOscarJ/src/stdafx.h120
-rw-r--r--protocols/IcqOscarJ/src/stdpackets.cpp1798
-rw-r--r--protocols/IcqOscarJ/src/stdpackets.h43
-rw-r--r--protocols/IcqOscarJ/src/tlv.cpp341
-rw-r--r--protocols/IcqOscarJ/src/tlv.h76
-rw-r--r--protocols/IcqOscarJ/src/upload.cpp86
-rw-r--r--protocols/IcqOscarJ/src/userinfotab.cpp290
-rw-r--r--protocols/IcqOscarJ/src/utilities.cpp1695
-rw-r--r--protocols/IcqOscarJ/src/utilities.h135
-rw-r--r--protocols/IcqOscarJ/src/version.h13
201 files changed, 263 insertions, 39134 deletions
diff --git a/protocols/Icq10/icq10.vcxproj b/protocols/Icq10/icq10.vcxproj
index d780943e95..98fb8261e0 100644
--- a/protocols/Icq10/icq10.vcxproj
+++ b/protocols/Icq10/icq10.vcxproj
@@ -19,7 +19,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectName>Icq</ProjectName>
+ <ProjectName>ICQ</ProjectName>
<ProjectGuid>{EFB2355B-82B3-4759-B7D8-95F8E9506291}</ProjectGuid>
</PropertyGroup>
<ImportGroup Label="PropertySheets">
diff --git a/protocols/IcqOscarJ/icq_xstatus/CMakeLists.txt b/protocols/Icq10/icq_xstatus/CMakeLists.txt
index 388679a148..388679a148 100644
--- a/protocols/IcqOscarJ/icq_xstatus/CMakeLists.txt
+++ b/protocols/Icq10/icq_xstatus/CMakeLists.txt
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/ICONS.rc b/protocols/Icq10/icq_xstatus/res/ICONS.rc
index 3c6fbe73e6..668fcaa7fb 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/ICONS.rc
+++ b/protocols/Icq10/icq_xstatus/res/ICONS.rc
@@ -1,132 +1,132 @@
-//Microsoft Developer Studio generated resource script.
-//
-#include "..\src\resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "winres.h"
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDI_XSTATUS1 ICON "xstatus01.ico"
-IDI_XSTATUS2 ICON "xstatus02.ico"
-IDI_XSTATUS3 ICON "xstatus03.ico"
-IDI_XSTATUS4 ICON "xstatus04.ico"
-IDI_XSTATUS5 ICON "xstatus05.ico"
-IDI_XSTATUS6 ICON "xstatus06.ico"
-IDI_XSTATUS7 ICON "xstatus07.ico"
-IDI_XSTATUS8 ICON "xstatus08.ico"
-IDI_XSTATUS9 ICON "xstatus09.ico"
-IDI_XSTATUS10 ICON "xstatus10.ico"
-IDI_XSTATUS11 ICON "xstatus11.ico"
-IDI_XSTATUS12 ICON "xstatus12.ico"
-IDI_XSTATUS13 ICON "xstatus13.ico"
-IDI_XSTATUS14 ICON "xstatus14.ico"
-IDI_XSTATUS15 ICON "xstatus15.ico"
-IDI_XSTATUS16 ICON "xstatus16.ico"
-IDI_XSTATUS17 ICON "xstatus17.ico"
-IDI_XSTATUS18 ICON "xstatus18.ico"
-IDI_XSTATUS19 ICON "xstatus19.ico"
-IDI_XSTATUS20 ICON "xstatus20.ico"
-IDI_XSTATUS21 ICON "xstatus21.ico"
-IDI_XSTATUS22 ICON "xstatus22.ico"
-IDI_XSTATUS23 ICON "xstatus23.ico"
-IDI_XSTATUS24 ICON "xstatus24.ico"
-IDI_XSTATUS25 ICON "xstatus25.ico"
-IDI_XSTATUS26 ICON "xstatus26.ico"
-IDI_XSTATUS27 ICON "xstatus27.ico"
-IDI_XSTATUS28 ICON "xstatus28.ico"
-IDI_XSTATUS29 ICON "xstatus29.ico"
-IDI_XSTATUS30 ICON "xstatus30.ico"
-IDI_XSTATUS31 ICON "xstatus31.ico"
-IDI_XSTATUS32 ICON "xstatus32.ico"
-IDI_XSTATUS33 ICON "xstatus33.ico"
-IDI_XSTATUS34 ICON "xstatus34.ico"
-IDI_XSTATUS35 ICON "xstatus35.ico"
-IDI_XSTATUS36 ICON "xstatus36.ico"
-IDI_XSTATUS37 ICON "xstatus37.ico"
-IDI_XSTATUS38 ICON "xstatus38.ico"
-IDI_XSTATUS39 ICON "xstatus39.ico"
-IDI_XSTATUS40 ICON "xstatus40.ico"
-IDI_XSTATUS41 ICON "xstatus41.ico"
-IDI_XSTATUS42 ICON "xstatus42.ico"
-IDI_XSTATUS43 ICON "xstatus43.ico"
-IDI_XSTATUS44 ICON "xstatus44.ico"
-IDI_XSTATUS45 ICON "xstatus45.ico"
-IDI_XSTATUS46 ICON "xstatus46.ico"
-IDI_XSTATUS47 ICON "xstatus47.ico"
-IDI_XSTATUS48 ICON "xstatus48.ico"
-IDI_XSTATUS49 ICON "xstatus49.ico"
-IDI_XSTATUS50 ICON "xstatus50.ico"
-IDI_XSTATUS51 ICON "xstatus51.ico"
-IDI_XSTATUS52 ICON "xstatus52.ico"
-IDI_XSTATUS53 ICON "xstatus53.ico"
-IDI_XSTATUS54 ICON "xstatus54.ico"
-IDI_XSTATUS55 ICON "xstatus55.ico"
-IDI_XSTATUS56 ICON "xstatus56.ico"
-IDI_XSTATUS57 ICON "xstatus57.ico"
-IDI_XSTATUS58 ICON "xstatus58.ico"
-IDI_XSTATUS59 ICON "xstatus59.ico"
-IDI_XSTATUS60 ICON "xstatus60.ico"
-IDI_XSTATUS61 ICON "xstatus61.ico"
-IDI_XSTATUS62 ICON "xstatus62.ico"
-IDI_XSTATUS63 ICON "xstatus63.ico"
-IDI_XSTATUS64 ICON "xstatus64.ico"
-IDI_XSTATUS65 ICON "xstatus65.ico"
-IDI_XSTATUS66 ICON "xstatus66.ico"
-IDI_XSTATUS67 ICON "xstatus67.ico"
-IDI_XSTATUS68 ICON "xstatus68.ico"
-IDI_XSTATUS69 ICON "xstatus69.ico"
-IDI_XSTATUS70 ICON "xstatus70.ico"
-IDI_XSTATUS71 ICON "xstatus71.ico"
-IDI_XSTATUS72 ICON "xstatus72.ico"
-IDI_XSTATUS73 ICON "xstatus73.ico"
-IDI_XSTATUS74 ICON "xstatus74.ico"
-IDI_XSTATUS75 ICON "xstatus75.ico"
-IDI_XSTATUS76 ICON "xstatus76.ico"
-IDI_XSTATUS77 ICON "xstatus77.ico"
-IDI_XSTATUS78 ICON "xstatus78.ico"
-IDI_XSTATUS79 ICON "xstatus79.ico"
-IDI_XSTATUS80 ICON "xstatus80.ico"
-IDI_XSTATUS81 ICON "xstatus81.ico"
-IDI_XSTATUS82 ICON "xstatus82.ico"
-IDI_XSTATUS83 ICON "xstatus83.ico"
-IDI_XSTATUS84 ICON "xstatus84.ico"
-IDI_XSTATUS85 ICON "xstatus85.ico"
-IDI_XSTATUS86 ICON "xstatus86.ico"
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// String Table
-//
-
-STRINGTABLE
-BEGIN
- IDS_IDENTIFY "# Custom Status Icons #"
-END
-
-
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
+//Microsoft Developer Studio generated resource script.
+//
+#include "..\src\resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_XSTATUS1 ICON "xstatus01.ico"
+IDI_XSTATUS2 ICON "xstatus02.ico"
+IDI_XSTATUS3 ICON "xstatus03.ico"
+IDI_XSTATUS4 ICON "xstatus04.ico"
+IDI_XSTATUS5 ICON "xstatus05.ico"
+IDI_XSTATUS6 ICON "xstatus06.ico"
+IDI_XSTATUS7 ICON "xstatus07.ico"
+IDI_XSTATUS8 ICON "xstatus08.ico"
+IDI_XSTATUS9 ICON "xstatus09.ico"
+IDI_XSTATUS10 ICON "xstatus10.ico"
+IDI_XSTATUS11 ICON "xstatus11.ico"
+IDI_XSTATUS12 ICON "xstatus12.ico"
+IDI_XSTATUS13 ICON "xstatus13.ico"
+IDI_XSTATUS14 ICON "xstatus14.ico"
+IDI_XSTATUS15 ICON "xstatus15.ico"
+IDI_XSTATUS16 ICON "xstatus16.ico"
+IDI_XSTATUS17 ICON "xstatus17.ico"
+IDI_XSTATUS18 ICON "xstatus18.ico"
+IDI_XSTATUS19 ICON "xstatus19.ico"
+IDI_XSTATUS20 ICON "xstatus20.ico"
+IDI_XSTATUS21 ICON "xstatus21.ico"
+IDI_XSTATUS22 ICON "xstatus22.ico"
+IDI_XSTATUS23 ICON "xstatus23.ico"
+IDI_XSTATUS24 ICON "xstatus24.ico"
+IDI_XSTATUS25 ICON "xstatus25.ico"
+IDI_XSTATUS26 ICON "xstatus26.ico"
+IDI_XSTATUS27 ICON "xstatus27.ico"
+IDI_XSTATUS28 ICON "xstatus28.ico"
+IDI_XSTATUS29 ICON "xstatus29.ico"
+IDI_XSTATUS30 ICON "xstatus30.ico"
+IDI_XSTATUS31 ICON "xstatus31.ico"
+IDI_XSTATUS32 ICON "xstatus32.ico"
+IDI_XSTATUS33 ICON "xstatus33.ico"
+IDI_XSTATUS34 ICON "xstatus34.ico"
+IDI_XSTATUS35 ICON "xstatus35.ico"
+IDI_XSTATUS36 ICON "xstatus36.ico"
+IDI_XSTATUS37 ICON "xstatus37.ico"
+IDI_XSTATUS38 ICON "xstatus38.ico"
+IDI_XSTATUS39 ICON "xstatus39.ico"
+IDI_XSTATUS40 ICON "xstatus40.ico"
+IDI_XSTATUS41 ICON "xstatus41.ico"
+IDI_XSTATUS42 ICON "xstatus42.ico"
+IDI_XSTATUS43 ICON "xstatus43.ico"
+IDI_XSTATUS44 ICON "xstatus44.ico"
+IDI_XSTATUS45 ICON "xstatus45.ico"
+IDI_XSTATUS46 ICON "xstatus46.ico"
+IDI_XSTATUS47 ICON "xstatus47.ico"
+IDI_XSTATUS48 ICON "xstatus48.ico"
+IDI_XSTATUS49 ICON "xstatus49.ico"
+IDI_XSTATUS50 ICON "xstatus50.ico"
+IDI_XSTATUS51 ICON "xstatus51.ico"
+IDI_XSTATUS52 ICON "xstatus52.ico"
+IDI_XSTATUS53 ICON "xstatus53.ico"
+IDI_XSTATUS54 ICON "xstatus54.ico"
+IDI_XSTATUS55 ICON "xstatus55.ico"
+IDI_XSTATUS56 ICON "xstatus56.ico"
+IDI_XSTATUS57 ICON "xstatus57.ico"
+IDI_XSTATUS58 ICON "xstatus58.ico"
+IDI_XSTATUS59 ICON "xstatus59.ico"
+IDI_XSTATUS60 ICON "xstatus60.ico"
+IDI_XSTATUS61 ICON "xstatus61.ico"
+IDI_XSTATUS62 ICON "xstatus62.ico"
+IDI_XSTATUS63 ICON "xstatus63.ico"
+IDI_XSTATUS64 ICON "xstatus64.ico"
+IDI_XSTATUS65 ICON "xstatus65.ico"
+IDI_XSTATUS66 ICON "xstatus66.ico"
+IDI_XSTATUS67 ICON "xstatus67.ico"
+IDI_XSTATUS68 ICON "xstatus68.ico"
+IDI_XSTATUS69 ICON "xstatus69.ico"
+IDI_XSTATUS70 ICON "xstatus70.ico"
+IDI_XSTATUS71 ICON "xstatus71.ico"
+IDI_XSTATUS72 ICON "xstatus72.ico"
+IDI_XSTATUS73 ICON "xstatus73.ico"
+IDI_XSTATUS74 ICON "xstatus74.ico"
+IDI_XSTATUS75 ICON "xstatus75.ico"
+IDI_XSTATUS76 ICON "xstatus76.ico"
+IDI_XSTATUS77 ICON "xstatus77.ico"
+IDI_XSTATUS78 ICON "xstatus78.ico"
+IDI_XSTATUS79 ICON "xstatus79.ico"
+IDI_XSTATUS80 ICON "xstatus80.ico"
+IDI_XSTATUS81 ICON "xstatus81.ico"
+IDI_XSTATUS82 ICON "xstatus82.ico"
+IDI_XSTATUS83 ICON "xstatus83.ico"
+IDI_XSTATUS84 ICON "xstatus84.ico"
+IDI_XSTATUS85 ICON "xstatus85.ico"
+IDI_XSTATUS86 ICON "xstatus86.ico"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_IDENTIFY "# Custom Status Icons #"
+END
+
+
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus34.ico b/protocols/Icq10/icq_xstatus/res/Xstatus34.ico
index 94ff6c40a4..94ff6c40a4 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus34.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus34.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus35.ico b/protocols/Icq10/icq_xstatus/res/Xstatus35.ico
index c1ae60d128..c1ae60d128 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus35.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus35.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus36.ico b/protocols/Icq10/icq_xstatus/res/Xstatus36.ico
index 892feaccff..892feaccff 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus36.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus36.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus38.ico b/protocols/Icq10/icq_xstatus/res/Xstatus38.ico
index 65c209953c..65c209953c 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus38.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus38.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus39.ico b/protocols/Icq10/icq_xstatus/res/Xstatus39.ico
index 51f0d05c77..51f0d05c77 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus39.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus39.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus40.ico b/protocols/Icq10/icq_xstatus/res/Xstatus40.ico
index f6b4998e03..f6b4998e03 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus40.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus40.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus41.ico b/protocols/Icq10/icq_xstatus/res/Xstatus41.ico
index 33a36cecff..33a36cecff 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus41.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus41.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus42.ico b/protocols/Icq10/icq_xstatus/res/Xstatus42.ico
index 83b8bca967..83b8bca967 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus42.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus42.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus45.ico b/protocols/Icq10/icq_xstatus/res/Xstatus45.ico
index 32d2200070..32d2200070 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus45.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus45.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus46.ico b/protocols/Icq10/icq_xstatus/res/Xstatus46.ico
index 5db3cfe818..5db3cfe818 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus46.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus46.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus47.ico b/protocols/Icq10/icq_xstatus/res/Xstatus47.ico
index 7cadb8087b..7cadb8087b 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus47.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus47.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus48.ico b/protocols/Icq10/icq_xstatus/res/Xstatus48.ico
index c149ebb48d..c149ebb48d 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus48.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus48.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus49.ico b/protocols/Icq10/icq_xstatus/res/Xstatus49.ico
index 122d833056..122d833056 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus49.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus49.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus50.ico b/protocols/Icq10/icq_xstatus/res/Xstatus50.ico
index 036abfa0f4..036abfa0f4 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus50.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus50.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus51.ico b/protocols/Icq10/icq_xstatus/res/Xstatus51.ico
index 201720649f..201720649f 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus51.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus51.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus52.ico b/protocols/Icq10/icq_xstatus/res/Xstatus52.ico
index bcab27a17f..bcab27a17f 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus52.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus52.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus53.ico b/protocols/Icq10/icq_xstatus/res/Xstatus53.ico
index 96f0c68511..96f0c68511 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus53.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus53.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus54.ico b/protocols/Icq10/icq_xstatus/res/Xstatus54.ico
index 6f9e0e3067..6f9e0e3067 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus54.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus54.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus56.ico b/protocols/Icq10/icq_xstatus/res/Xstatus56.ico
index 6d43039218..6d43039218 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus56.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus56.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus57.ico b/protocols/Icq10/icq_xstatus/res/Xstatus57.ico
index 97b9e8e44e..97b9e8e44e 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus57.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus57.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus58.ico b/protocols/Icq10/icq_xstatus/res/Xstatus58.ico
index 40392dfead..40392dfead 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus58.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus58.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus59.ico b/protocols/Icq10/icq_xstatus/res/Xstatus59.ico
index 10af7631fd..10af7631fd 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus59.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus59.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus60.ico b/protocols/Icq10/icq_xstatus/res/Xstatus60.ico
index 3e1970be6b..3e1970be6b 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus60.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus60.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus61.ico b/protocols/Icq10/icq_xstatus/res/Xstatus61.ico
index fa36473e21..fa36473e21 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus61.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus61.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus62.ico b/protocols/Icq10/icq_xstatus/res/Xstatus62.ico
index 886e5f076e..886e5f076e 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus62.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus62.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus63.ico b/protocols/Icq10/icq_xstatus/res/Xstatus63.ico
index 907ed2801b..907ed2801b 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus63.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus63.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus65.ico b/protocols/Icq10/icq_xstatus/res/Xstatus65.ico
index 5220b812f4..5220b812f4 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus65.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus65.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus66.ico b/protocols/Icq10/icq_xstatus/res/Xstatus66.ico
index 6b102a202b..6b102a202b 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus66.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus66.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus67.ico b/protocols/Icq10/icq_xstatus/res/Xstatus67.ico
index ad4347a10d..ad4347a10d 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus67.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus67.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus68.ico b/protocols/Icq10/icq_xstatus/res/Xstatus68.ico
index 33e635fe8f..33e635fe8f 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus68.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus68.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus69.ico b/protocols/Icq10/icq_xstatus/res/Xstatus69.ico
index 128135a9f9..128135a9f9 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus69.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus69.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus70.ico b/protocols/Icq10/icq_xstatus/res/Xstatus70.ico
index ea98a53942..ea98a53942 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus70.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus70.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus71.ico b/protocols/Icq10/icq_xstatus/res/Xstatus71.ico
index 74a2ba1a0e..74a2ba1a0e 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus71.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus71.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus72.ico b/protocols/Icq10/icq_xstatus/res/Xstatus72.ico
index 331175fb09..331175fb09 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus72.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus72.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus73.ico b/protocols/Icq10/icq_xstatus/res/Xstatus73.ico
index 395c83b749..395c83b749 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus73.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus73.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus74.ico b/protocols/Icq10/icq_xstatus/res/Xstatus74.ico
index 2d51be6ca0..2d51be6ca0 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus74.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus74.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus75.ico b/protocols/Icq10/icq_xstatus/res/Xstatus75.ico
index eb12fd82e5..eb12fd82e5 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus75.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus75.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus76.ico b/protocols/Icq10/icq_xstatus/res/Xstatus76.ico
index e7f0641f54..e7f0641f54 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus76.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus76.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus77.ico b/protocols/Icq10/icq_xstatus/res/Xstatus77.ico
index 843e9a6d89..843e9a6d89 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus77.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus77.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus78.ico b/protocols/Icq10/icq_xstatus/res/Xstatus78.ico
index 7ac7984d39..7ac7984d39 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus78.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus78.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus79.ico b/protocols/Icq10/icq_xstatus/res/Xstatus79.ico
index c88ef8d6fc..c88ef8d6fc 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus79.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus79.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus81.ico b/protocols/Icq10/icq_xstatus/res/Xstatus81.ico
index e48756ce0b..e48756ce0b 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus81.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus81.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus82.ico b/protocols/Icq10/icq_xstatus/res/Xstatus82.ico
index 68d036dd2e..68d036dd2e 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus82.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus82.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus83.ico b/protocols/Icq10/icq_xstatus/res/Xstatus83.ico
index fd62cc5930..fd62cc5930 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus83.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus83.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus84.ico b/protocols/Icq10/icq_xstatus/res/Xstatus84.ico
index e5b4401eca..e5b4401eca 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus84.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus84.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus86.ico b/protocols/Icq10/icq_xstatus/res/Xstatus86.ico
index baa5fb890a..baa5fb890a 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus86.ico
+++ b/protocols/Icq10/icq_xstatus/res/Xstatus86.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus01.ico b/protocols/Icq10/icq_xstatus/res/xstatus01.ico
index d93292e5de..d93292e5de 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus01.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus01.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus02.ico b/protocols/Icq10/icq_xstatus/res/xstatus02.ico
index c79590ce55..c79590ce55 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus02.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus02.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus03.ico b/protocols/Icq10/icq_xstatus/res/xstatus03.ico
index 4e0bb4483e..4e0bb4483e 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus03.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus03.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus04.ico b/protocols/Icq10/icq_xstatus/res/xstatus04.ico
index ad969ee16f..ad969ee16f 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus04.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus04.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus05.ico b/protocols/Icq10/icq_xstatus/res/xstatus05.ico
index 8de50069f0..8de50069f0 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus05.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus05.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus06.ico b/protocols/Icq10/icq_xstatus/res/xstatus06.ico
index d2c3719c0e..d2c3719c0e 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus06.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus06.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus07.ico b/protocols/Icq10/icq_xstatus/res/xstatus07.ico
index b255150af3..b255150af3 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus07.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus07.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus08.ico b/protocols/Icq10/icq_xstatus/res/xstatus08.ico
index efe963ed08..efe963ed08 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus08.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus08.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus09.ico b/protocols/Icq10/icq_xstatus/res/xstatus09.ico
index e2d763604f..e2d763604f 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus09.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus09.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus10.ico b/protocols/Icq10/icq_xstatus/res/xstatus10.ico
index fa35edc7cb..fa35edc7cb 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus10.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus10.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus11.ico b/protocols/Icq10/icq_xstatus/res/xstatus11.ico
index 45a4e37e26..45a4e37e26 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus11.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus11.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus12.ico b/protocols/Icq10/icq_xstatus/res/xstatus12.ico
index 43141a82d7..43141a82d7 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus12.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus12.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus13.ico b/protocols/Icq10/icq_xstatus/res/xstatus13.ico
index 0cf43cf279..0cf43cf279 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus13.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus13.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus14.ico b/protocols/Icq10/icq_xstatus/res/xstatus14.ico
index 0f642c0a4a..0f642c0a4a 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus14.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus14.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus15.ico b/protocols/Icq10/icq_xstatus/res/xstatus15.ico
index 7927b650a8..7927b650a8 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus15.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus15.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus16.ico b/protocols/Icq10/icq_xstatus/res/xstatus16.ico
index 8f9da9944a..8f9da9944a 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus16.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus16.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus17.ico b/protocols/Icq10/icq_xstatus/res/xstatus17.ico
index a9d0eda3fd..a9d0eda3fd 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus17.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus17.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus18.ico b/protocols/Icq10/icq_xstatus/res/xstatus18.ico
index 4206311c4c..4206311c4c 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus18.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus18.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus19.ico b/protocols/Icq10/icq_xstatus/res/xstatus19.ico
index 63711f9c34..63711f9c34 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus19.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus19.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus20.ico b/protocols/Icq10/icq_xstatus/res/xstatus20.ico
index ca25ab0335..ca25ab0335 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus20.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus20.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus21.ico b/protocols/Icq10/icq_xstatus/res/xstatus21.ico
index d3b1bf62e3..d3b1bf62e3 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus21.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus21.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus22.ico b/protocols/Icq10/icq_xstatus/res/xstatus22.ico
index d74acd732f..d74acd732f 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus22.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus22.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus23.ico b/protocols/Icq10/icq_xstatus/res/xstatus23.ico
index ef7a8fe956..ef7a8fe956 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus23.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus23.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus24.ico b/protocols/Icq10/icq_xstatus/res/xstatus24.ico
index 549b0eaa65..549b0eaa65 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus24.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus24.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus25.ico b/protocols/Icq10/icq_xstatus/res/xstatus25.ico
index 5675d95785..5675d95785 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus25.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus25.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus26.ico b/protocols/Icq10/icq_xstatus/res/xstatus26.ico
index 65f14175cb..65f14175cb 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus26.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus26.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus27.ico b/protocols/Icq10/icq_xstatus/res/xstatus27.ico
index 873695f154..873695f154 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus27.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus27.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus28.ico b/protocols/Icq10/icq_xstatus/res/xstatus28.ico
index 46d29dabdd..46d29dabdd 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus28.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus28.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus29.ico b/protocols/Icq10/icq_xstatus/res/xstatus29.ico
index b6c8410b9f..b6c8410b9f 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus29.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus29.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus30.ico b/protocols/Icq10/icq_xstatus/res/xstatus30.ico
index 9776f8196c..9776f8196c 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus30.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus30.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus31.ico b/protocols/Icq10/icq_xstatus/res/xstatus31.ico
index 92e459b096..92e459b096 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus31.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus31.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus32.ico b/protocols/Icq10/icq_xstatus/res/xstatus32.ico
index 37d1fa0978..37d1fa0978 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus32.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus32.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus33.ico b/protocols/Icq10/icq_xstatus/res/xstatus33.ico
index a86ecbc90f..a86ecbc90f 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus33.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus33.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus37.ico b/protocols/Icq10/icq_xstatus/res/xstatus37.ico
index dc4c382e61..dc4c382e61 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus37.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus37.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus43.ico b/protocols/Icq10/icq_xstatus/res/xstatus43.ico
index 383b0fe278..383b0fe278 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus43.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus43.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus44.ico b/protocols/Icq10/icq_xstatus/res/xstatus44.ico
index 38424cadb5..38424cadb5 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus44.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus44.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus55.ico b/protocols/Icq10/icq_xstatus/res/xstatus55.ico
index a77522c71f..a77522c71f 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus55.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus55.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus64.ico b/protocols/Icq10/icq_xstatus/res/xstatus64.ico
index 4937cdd920..4937cdd920 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus64.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus64.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus80.ico b/protocols/Icq10/icq_xstatus/res/xstatus80.ico
index 5db9c25f61..5db9c25f61 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus80.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus80.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus85.ico b/protocols/Icq10/icq_xstatus/res/xstatus85.ico
index 20af670137..20af670137 100644
--- a/protocols/IcqOscarJ/icq_xstatus/res/xstatus85.ico
+++ b/protocols/Icq10/icq_xstatus/res/xstatus85.ico
Binary files differ
diff --git a/protocols/IcqOscarJ/icq_xstatus/src/resource.h b/protocols/Icq10/icq_xstatus/src/resource.h
index ce4127c0a6..fecb45999e 100644
--- a/protocols/IcqOscarJ/icq_xstatus/src/resource.h
+++ b/protocols/Icq10/icq_xstatus/src/resource.h
@@ -1,103 +1,103 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by resources.rc
-//
-#define IDI_XSTATUS1 201
-#define IDI_XSTATUS2 202
-#define IDI_XSTATUS3 203
-#define IDI_XSTATUS4 204
-#define IDI_XSTATUS5 205
-#define IDI_XSTATUS6 206
-#define IDI_XSTATUS7 207
-#define IDI_XSTATUS8 208
-#define IDI_XSTATUS9 209
-#define IDI_XSTATUS10 210
-#define IDI_XSTATUS11 211
-#define IDI_XSTATUS12 212
-#define IDI_XSTATUS13 213
-#define IDI_XSTATUS14 214
-#define IDI_XSTATUS15 215
-#define IDI_XSTATUS16 216
-#define IDI_XSTATUS17 217
-#define IDI_XSTATUS18 218
-#define IDI_XSTATUS19 219
-#define IDI_XSTATUS20 220
-#define IDI_XSTATUS21 221
-#define IDI_XSTATUS22 222
-#define IDI_XSTATUS23 223
-#define IDI_XSTATUS24 224
-#define IDI_XSTATUS25 225
-#define IDI_XSTATUS26 226
-#define IDI_XSTATUS27 227
-#define IDI_XSTATUS28 228
-#define IDI_XSTATUS29 229
-#define IDI_XSTATUS30 230
-#define IDI_XSTATUS31 231
-#define IDI_XSTATUS32 232
-#define IDI_XSTATUS33 233
-#define IDI_XSTATUS34 234
-#define IDI_XSTATUS35 235
-#define IDI_XSTATUS36 236
-#define IDI_XSTATUS37 237
-#define IDI_XSTATUS38 238
-#define IDI_XSTATUS39 239
-#define IDI_XSTATUS40 240
-#define IDI_XSTATUS41 241
-#define IDI_XSTATUS42 242
-#define IDI_XSTATUS43 243
-#define IDI_XSTATUS44 244
-#define IDI_XSTATUS45 245
-#define IDI_XSTATUS46 246
-#define IDI_XSTATUS47 247
-#define IDI_XSTATUS48 248
-#define IDI_XSTATUS49 249
-#define IDI_XSTATUS50 250
-#define IDI_XSTATUS51 251
-#define IDI_XSTATUS52 252
-#define IDI_XSTATUS53 253
-#define IDI_XSTATUS54 254
-#define IDI_XSTATUS55 255
-#define IDI_XSTATUS56 256
-#define IDI_XSTATUS57 257
-#define IDI_XSTATUS58 258
-#define IDI_XSTATUS59 259
-#define IDI_XSTATUS60 260
-#define IDI_XSTATUS61 261
-#define IDI_XSTATUS62 262
-#define IDI_XSTATUS63 263
-#define IDI_XSTATUS64 264
-#define IDI_XSTATUS65 265
-#define IDI_XSTATUS66 266
-#define IDI_XSTATUS67 267
-#define IDI_XSTATUS68 268
-#define IDI_XSTATUS69 269
-#define IDI_XSTATUS70 270
-#define IDI_XSTATUS71 271
-#define IDI_XSTATUS72 272
-#define IDI_XSTATUS73 273
-#define IDI_XSTATUS74 274
-#define IDI_XSTATUS75 275
-#define IDI_XSTATUS76 276
-#define IDI_XSTATUS77 277
-#define IDI_XSTATUS78 278
-#define IDI_XSTATUS79 279
-#define IDI_XSTATUS80 280
-#define IDI_XSTATUS81 281
-#define IDI_XSTATUS82 282
-#define IDI_XSTATUS83 283
-#define IDI_XSTATUS84 284
-#define IDI_XSTATUS85 285
-#define IDI_XSTATUS86 286
-
-#define IDS_IDENTIFY 102
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 113
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1026
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resources.rc
+//
+#define IDI_XSTATUS1 201
+#define IDI_XSTATUS2 202
+#define IDI_XSTATUS3 203
+#define IDI_XSTATUS4 204
+#define IDI_XSTATUS5 205
+#define IDI_XSTATUS6 206
+#define IDI_XSTATUS7 207
+#define IDI_XSTATUS8 208
+#define IDI_XSTATUS9 209
+#define IDI_XSTATUS10 210
+#define IDI_XSTATUS11 211
+#define IDI_XSTATUS12 212
+#define IDI_XSTATUS13 213
+#define IDI_XSTATUS14 214
+#define IDI_XSTATUS15 215
+#define IDI_XSTATUS16 216
+#define IDI_XSTATUS17 217
+#define IDI_XSTATUS18 218
+#define IDI_XSTATUS19 219
+#define IDI_XSTATUS20 220
+#define IDI_XSTATUS21 221
+#define IDI_XSTATUS22 222
+#define IDI_XSTATUS23 223
+#define IDI_XSTATUS24 224
+#define IDI_XSTATUS25 225
+#define IDI_XSTATUS26 226
+#define IDI_XSTATUS27 227
+#define IDI_XSTATUS28 228
+#define IDI_XSTATUS29 229
+#define IDI_XSTATUS30 230
+#define IDI_XSTATUS31 231
+#define IDI_XSTATUS32 232
+#define IDI_XSTATUS33 233
+#define IDI_XSTATUS34 234
+#define IDI_XSTATUS35 235
+#define IDI_XSTATUS36 236
+#define IDI_XSTATUS37 237
+#define IDI_XSTATUS38 238
+#define IDI_XSTATUS39 239
+#define IDI_XSTATUS40 240
+#define IDI_XSTATUS41 241
+#define IDI_XSTATUS42 242
+#define IDI_XSTATUS43 243
+#define IDI_XSTATUS44 244
+#define IDI_XSTATUS45 245
+#define IDI_XSTATUS46 246
+#define IDI_XSTATUS47 247
+#define IDI_XSTATUS48 248
+#define IDI_XSTATUS49 249
+#define IDI_XSTATUS50 250
+#define IDI_XSTATUS51 251
+#define IDI_XSTATUS52 252
+#define IDI_XSTATUS53 253
+#define IDI_XSTATUS54 254
+#define IDI_XSTATUS55 255
+#define IDI_XSTATUS56 256
+#define IDI_XSTATUS57 257
+#define IDI_XSTATUS58 258
+#define IDI_XSTATUS59 259
+#define IDI_XSTATUS60 260
+#define IDI_XSTATUS61 261
+#define IDI_XSTATUS62 262
+#define IDI_XSTATUS63 263
+#define IDI_XSTATUS64 264
+#define IDI_XSTATUS65 265
+#define IDI_XSTATUS66 266
+#define IDI_XSTATUS67 267
+#define IDI_XSTATUS68 268
+#define IDI_XSTATUS69 269
+#define IDI_XSTATUS70 270
+#define IDI_XSTATUS71 271
+#define IDI_XSTATUS72 272
+#define IDI_XSTATUS73 273
+#define IDI_XSTATUS74 274
+#define IDI_XSTATUS75 275
+#define IDI_XSTATUS76 276
+#define IDI_XSTATUS77 277
+#define IDI_XSTATUS78 278
+#define IDI_XSTATUS79 279
+#define IDI_XSTATUS80 280
+#define IDI_XSTATUS81 281
+#define IDI_XSTATUS82 282
+#define IDI_XSTATUS83 283
+#define IDI_XSTATUS84 284
+#define IDI_XSTATUS85 285
+#define IDI_XSTATUS86 286
+
+#define IDS_IDENTIFY 102
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 113
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1026
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/protocols/IcqOscarJ/icq_xstatus/xStatus_ICQ.vcxproj b/protocols/Icq10/icq_xstatus/xStatus_ICQ.vcxproj
index 0cad4d6682..0b0e04a799 100644
--- a/protocols/IcqOscarJ/icq_xstatus/xStatus_ICQ.vcxproj
+++ b/protocols/Icq10/icq_xstatus/xStatus_ICQ.vcxproj
@@ -1,28 +1,28 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectName>xStatus_ICQ</ProjectName>
- <ProjectGuid>{E98A8615-1082-1979-D6D8-F763F13BFCBD}</ProjectGuid>
- </PropertyGroup>
- <ImportGroup Label="PropertySheets">
- <Import Project="$(ProjectDir)..\..\..\build\vc.common\icons.props" />
- </ImportGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>xStatus_ICQ</ProjectName>
+ <ProjectGuid>{E98A8615-1082-1979-D6D8-F763F13BFCBD}</ProjectGuid>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(ProjectDir)..\..\..\build\vc.common\icons.props" />
+ </ImportGroup>
</Project> \ No newline at end of file
diff --git a/protocols/IcqOscarJ/CMakeLists.txt b/protocols/IcqOscarJ/CMakeLists.txt
deleted file mode 100644
index c5feb2c951..0000000000
--- a/protocols/IcqOscarJ/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-file(GLOB SOURCES "src/*.h" "src/*.cpp" "res/*.rc")
-set(TARGET ICQ)
-include(${CMAKE_SOURCE_DIR}/cmake/plugin.cmake)
-target_link_libraries(${TARGET} comctl32.lib ws2_32.lib)
-add_subdirectory(proto_icq)
-add_subdirectory(icq_xstatus) \ No newline at end of file
diff --git a/protocols/IcqOscarJ/docs/license.txt b/protocols/IcqOscarJ/docs/license.txt
deleted file mode 100644
index 7f1161073d..0000000000
--- a/protocols/IcqOscarJ/docs/license.txt
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- 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
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/protocols/IcqOscarJ/docs/readme.txt b/protocols/IcqOscarJ/docs/readme.txt
deleted file mode 100644
index a683d8cd72..0000000000
--- a/protocols/IcqOscarJ/docs/readme.txt
+++ /dev/null
@@ -1,480 +0,0 @@
-
- ICQ protocol plugin for Miranda IM (Joe)
- ________________________________________
-
-
-About
-_____
-
-This Miranda IM plugin makes it possible to connect to the ICQ
-instant messenger network and communicate with other ICQ users.
-
-
-Known Problems
-______________
-
-- In Invisible mode, when other side is not in visible list messages are sometimes
- received twice from some clients (it is a problem of that clients, they do send them
- twice)
-
-- When synchronising server-list, users get added with await auth flag or receive added
- message. The way which ICQ servers handle authorizations, we cannot do it better - when
- uploading contacts to server account has to be a new one, then contacts can be added
- and uploaded without auth... If the account is an old one they cannot be added without
- auth if they require one. So they are added with flag awaiting auth. With the new
- Manage server list contacts added contacts should never receive auth requests, but
- if you have an old account they can receive added notification.
-
-- Some wicked firewall software can cause HTML tags (e.g. <font> </font>) to be added to
- incoming messages.
-
-- With HTTP Proxy Mode in Connection settings, neither Avatars nor File Transfer can work.
- This is partly a limitation of current Miranda's network module implementation. But
- File Transfer cannot work with HTTP Proxy, that is a protocol limitation.
-
-
-TO-DO List
-__________
-
-0.6
- Multi-user chat
- Mid-NetLib module for HTTP gateway (for Avatars to work) [icq_net]
-
-0.5
- Full support for sub-groups in Manage server-list dialog
- Simple sub-groups support (optional)
-
-
-
-Changes
-_______
-
-0.5 Development
-
-Bugfixes:
- Fixed receiving of multi-part messages (only first part was received)
- Fixed processing of UTF-8 encoded status messages from QIP
- Fixed AIM away message handling (caused online status to be seen as away in some clients)
-
-New Features
- Account management (requires Miranda IM 0.8 and newer)
- New user details protocol support
- Added support for status notes & moods (introduced by ICQ6)
-
-Improvements:
- URL events are now received as normal messages
- Use new offline messages protocol (supports unicode)
- Ability to send/receive contacts to/from ICQ6 and AIM
- Server-list support now groups requests - much more faster & reliable
- Improved ChangeInfo module compatibility with screen readers
- Client detection improvements
- Avatars are now retrieved even for offline contacts
-
-
-0.3.9.5
-
-Bugfixes:
- Fixed connection problems with many contacts in server-list
- Do not lose server-list contacts due to too long nicknames/comments
-
-Improvements:
- Reinvented known spam bot blocking
-
-
-0.3.9.4
-
-Improvements:
- Added ability to handle malformed UCS-2 encoded offline messages
- Fixed possible local buffer overflow
-
-
-0.3.9.3
-
-Bugfixes:
- Fixed problem with utf-8 message API and some message plugins (weird chars)
- Fixed double Avatar pages in User Details for newer Miranda IM
-
-
-0.3.9.2
-
-Bugfixes:
- Fixed possible memory corruption caused by malformed langpack
- Added support for new utf-8 message API (when available)
- Fixed possible rare problems with Folders plug-in support
- Other minor fixes merged from trunk (0.3.10.x Development)
-
-
-0.3.9.1
-
-Bugfixes:
- Fixes several minor problems
-
-Improvements:
- Oscar File Transfers now fully handle directory transfers
-
-
-0.3.9
-
-Bugfixes:
- Fixed peer-to-peer session cookie checking (was working only due to coincidence)
- Fixed SMS message handling, made message parsing more consistent
- Applied fix for re-requesting authorization (thx Bio)
- Fixed handling of message acks & status msg replies from ICQ 6
- Fixed handling of malformed messages acks
- Minor fixes for Popup plugin support
- Minor protocol related tweaks
- Fixed possible lags caused by typing notifications (on slow connections)
- Fixed message handling (fixes bug used for stealth invisibility detection)
- Several fixes to Rate Level 2 handling - more propper handling of message responses
-
-New Features:
- Oscar File Transfers - like icq5 (including: transfer thru server, resume)
-
-Improvements:
- Client detection improvements
- Level 1 Rate management (global) - should solve problems with many contacts in list
- Support for Custom Profile Folders plug-in - configurable avatars cache folder
- Ability to send long offline messages (up to 4096 characters)
- Messsage Error handling is now complete (no more disconnections on long msgs)
- Support for Aim contacts enhanced
- Better support for Miranda Ignore module
-
-
-0.3.7.5
-
-Bugfixes:
- Fixed possible crash in avatar queue
- Fixed special character conversion in Custom Status messages
- Minor changes to client detection
-
-
-0.3.7.4
-
-Bugfixes:
- Some small fixes to Custom Status API
- Fixed possible buffer overrun problem in status change packet handling
- Some avatar related fixes
-
-Improvements:
- Added avatar validity checking
-
-
-0.3.7.3
-
-Bugfixes:
- Fixed HTTP/HTTPS proxy support (removed useless gateway option), long messages are now sent properly
- Improved status change handling (can handle broken packets)
-
-
-0.3.7.2
-
-Bugfixes:
- Fixes possible buffer overflow with contact status change
- Fixed migration was not working at all (should not disconnect so often on server's upgrading)
- Fixed offline greeting cards were not processed properly
- Fixed small protocol glitch with reverse peer-to-peer connection
-
-
-0.3.7.1
-
-Bugfixes:
- Fixed possible hang on exit
- Fixed avatars were not working when server port set to 0
- Made message parser more strict (fixes bug allowing stealth invisible client detection)
- Fixed Popup's unicode support cannot be used in ANSI mode even if available
-
-Improvements:
- Added new session password API - allowing plugins like Secure Login to work better
-
-
-0.3.7
-
-Bugfixes:
- Our own contact in list now correctly handles events
- Proxy Gateway mode is working again
- File receiving from Trillian clients work again
- Incorporated some bugfixes from ISee (thx Bio)
- Message errors are now really displayed
- Fixed memory leak in avatar code
- File transfers with GnomeICU works now
- Fixed changing password in ICQ Details will not save it to DB if not there
- Fixed PING channel handling (caused connection drop)
- Fixed bug in changeinfo with translated listbox values (thx Bio)
- Fixed error handling in avatar code for uploading avatar
- Fixed bug in Manage-Server list dialog, caused hang
- Fixed occasional losing of messages (message parsing was incomplete)
- Server-list management now stores all info - solves problems
- Fixed unknown errors during login were not reported sometimes
-
-New Features:
- Messaging support enhanced (P2P messaging supported)
- Direct Connection support rewritten (with P2P messaging and reverse file-transfers)
- Temporary Visible List support
- New Features page in options to configure extra features
- Custom statuses just like icq5 - needs clist_mw derivative (thx Big Muscle)
- New custom status icons (thx Angeli-ka)
- Enhanced Unicode & Ansi charsets support (each contact can have its own codepage)
- AIM cross-compatability (add/remove, search by mail, status, messaging, away messages)
- Secure MD5 login authentification
- Revoke authorization (Advanced Feature - see further) - removes you from contact's server-list
-
-Improvements:
- Advanced search now can use newer method (thx Bio)
- Better protocol error handling
- Slightly better avatar handling
- Detects some spam bots & ability to block known spam bots
- Merged with ChangeInfo (thx Bio)
- Added possibility to remember password for session
- Added possibility to retrieve away message from libgaim clients
- Added status to UserInfo page
- Small improvements to client detection
- Uses newer capabilities format (cuts incoming traffic)
- Display error messages using PopUp Plugin
- Support for Iconlib Plugin
- Support for unicode database module (clist data)
- Level 2 Rate management for Status & Xtraz replies, Xtraz requests (useful with many contacts in list)
- Full unicode/ansi support (2in1)
- Support for Updater Plugin
- Added support for Flash Avatars Service Plugin
- Added ability to upload own flash avatar - XML file (thx Big Muscle)
-
-
-0.3.5.3
-
-Bugfixes:
- Fixed losing of almost all messages (protocol change)
-
-
-0.3.5.2
-
-Bugfixes:
- Error checking on offline messages was not working
- Now correctly handles "import time" item (should solve some auth issues)
-
-
-0.3.5.1
-
-Bugfixes:
- Renaming of server groups was not working properly - caused errors
- Avatar could not be deleted (the delete button did not work)
- File Transfers were not working properly in some cases (wrong cookie handling)
- Avatar formats were not recognized correctly
- Method of determining target dir in file receive was not solid enough
- Manage server-list dialog leaked memory
- Synchronize visibility items was not working properly
- Our avatar image was not linked to our ContactPhoto
- Added workaround for DB Blob caching issues
- Fixed occasional crash on login (missing TLV validity checks)
- Fixed slow update of nicks when users imported from server-list
- Fixed auto info update mechanism, do not progress too fast, do not drop processing
- Fixed empty groups are always hidden in Manage Server List, cannot be used either
- Fixed occasional crash on avatar retrieval - limit size of image to the size of packet
- If our rate is high, ignore user requests for status msgs & user details (prevents disconnection)
- Added temporary solution for roughly translated ICQ 2003b russian
- Manage server-list dialog could display other contacts and could crash
- Basic search could search for bad uin - garbage can be in the string
- Added workaround for select() malfunction - caused high CPU load
-
-Improvements:
- If Update details from server is on, user groups are also updated
- Changed System Uptime to Member since in my details
- Auth system recognizes & sends UTF-8 messages
- Miranda version signature improved (preparing for old signature removal in the future)
- Added better error detection for offline msgs receival process
- Made avatar handling more resilient to server errors
-
-
-0.3.5
-
-Bugfixes:
- Server-list operations is now scheduled correctly
- Newly added contact with privacy setting is not hidden anymore
- Fixed unicode message receiving from Icq2Go! (messages were corrupted)
- Fixed Grant authorization - not showed correctly and crashing randomly
- Move to group was not working properly
- On accept/decline filetransfer miranda was sometimes disconnected
- Group with subgroups was deleted if empty, that messed up subgroups
- Newly added contacts from server sometimes missed their group
- Offline messages are no longer received older than existing ones
- Now will not try to add contacts to server, which are not ours
- Divided server ids to groups - caused strange behaviour if id and group id were same
- Other small fixes
-
-New features:
- Added avatar tab to user-details dialog to show avatar even without mToolTip
- Linking avatar to mToolTip is now optional
- My user-details now show more informations & added idle since to ICQ tab
- Added support for uploading your own avatar image
-
-Improvements:
- Rewritten Manage Server List dialog - now works perfectly (without sub-groups support)
- Added partial support for subgroups (supported: rename, move, parial: add)
- Added optional linking to mToolTip, link only if no image set
- Added workaround for QNext client (it is not capable of type2 msgs)
- Added option to turn off HTTP gateway on HTTP proxy
-
-
-0.3.4.2 (not published)
-
-Bugfixes:
- Fixed authorization reply
- Fixed contact transfer ack
- Now parses URL send ack correctly, no more timeout
- Now sending ack on contacts receive
- Now correctly add contact without auth if they does not require it
- Fixed crash on receiving long message through P2P (very old bug)
- Many other fixes (see CVS changelog for details)
-
-New features:
- Added full unicode message support (requires SRMM Unicode)
- Added support for sending and receiving Idle time.
- Added reliable client identification (if not identified, gives appropriate ICQ client)
- Added support for avatar images (downloading only).
- Added Grant authorization option (send & recognize)
-
-Improvements:
- Server-side list support rewritten, now uses acking, partly supports groups (without sub-groups for now).
- Most cookies standardised to imitate icq5 behaviour
- Basic search now automatically removes garbage from text, e.g. it can search by 123-456-789
-
-
-0.3.3.1
-
-Bugfixes:
- Could crash when receiving unicode messages.
-
-
-0.3.3
-
-Bugfixes:
- Failed to send or receive files from ICQ 2003b.
- Fixed a number of smaller memory leaks.
- Contact e-mail info was not displayed correctly.
- Failed to retrieve user details during certain circumstances.
- URL messages could disappear when sent through a Direct Connection.
- Nick name was not deleted from server list when local nick name was deleted.
- Server side contacts could reappear after being deleted if they were on the
- visible/invisible lists.
- Changing status while connecting had no effect.
- A bunch of other fixes that are too boring to list here, have a look at
- the CVS changelog if you want the big list.
-
-New features:
- Added support for sending and receiving Typing Notifications.
- Now accepts messages formatted in unicode (note: this wont solve the problem
- with displaying messages with multiple charsets).
-
-Improvements:
- Uses plugin DLL name in various menus to make it easier to have several ICQ
- plugins loaded.
- More robust packet parsing reduces the risk of any future stability problems.
-
-
-0.3.2
-
-Bugfixes:
- Prevent your status messages being read when you are invisible.
- Small memory leak when sending an SMS.
- Fixed a dumb bug that caused random disconnections from the ICQ server.
- Cleaned up the code for searches and user info updates, should work better now.
- AIM users in your server contact list would get added locally with uin 0.
-
-New features:
- Added "missed message" notification.
-
-Improvements:
- Added better error messages for message send failures.
- Messages now default to the most reliable delivery method available for a given contact.
-
-
-0.3.1
-
-Bugfixes:
- Fixed crash when incoming file transfer was cancelled before the transfer started
- Failed to receive SMS messages sent while offline
- Fixed some problems with accepting file transfers from Mirabilis clients
- Increased thread safety to reduce some reported connection/disconnection problems
- Fixed compability problems with sending messages to some jabber clients
- Fixed some message compability problems with Trillian
- Corrected some ack sending
- Added a lot of safety checks to increase general stability
- Plugin didnt load unless winsocks2 was installed
-
-New features:
- Removed restrictions on UIN length for better compability with iserverd
- The password can now be left empty in options, it will be asked for during login
- Server port can now be left empty in options, a random port will be selected during login
- Show logged on since and system uptime info in ICQ tab
-
-Improvements:
- Reduced file size
- Message sending now uses a more reliable delivery method
-
-
-
-Support and bug reporting
-_________________________
-
-We cannot give support on e-mail or ICQ. Please visit the Miranda IM help page at
-http://www.miranda-im.org/help/ if you need help with this plugin.
-
-If the help page does answer your question, visit the Miranda support forum at:
-http://forums.miranda-im.org/ and we will try to assist you.
-
-If you want to report a bug, please do so in the official bugtracker at:
-http://bugs.miranda-im.org/
-
-
-
-Contact
-_______
-
-Current maintainer is Joe @ Whale, jokusoftware at miranda-im.org
-
-
-
-Advanced Features
-_________________
-
-There are some features that are not widely used so there is no UI for them, if
-you want to use them you need to do manual setup using DBE++.
-
-Database items (usually at Contact\ICQ):
-(BYTE)UnicodeSend = 0 - to Disable unicode support (useful as a workaround for Trillian's bug)
-
-(WORD)CodePage - codepage for plain text encoding/decoding to/from unicode
-
-(WORD)InfoCodePage - codepage for interpreting user details
-
-Database items for Main Contact (usually at Settings\ICQ):
-(DWORD)KeepAliveInterval - Period in which Keep-Alive packets are send if enabled - default is one minute
-
-(BYTE)PrivacyItems = 1 - adds more privacy tools to contact menu (e.g. Revoke Authorization)
-
-
-
-Credits and Thanks
-__________________
-
-Thanks to Angeli-Ka for nice custom status icons.
-
-
-
-License and Copyright
-_____________________
-
-Copyright (C) 2000-2010 Joe Kucera, Martin Öberg, Richard Hughes, Jon Keating
-
-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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
diff --git a/protocols/IcqOscarJ/icqoscar8.vcxproj b/protocols/IcqOscarJ/icqoscar8.vcxproj
deleted file mode 100644
index b76e4171b6..0000000000
--- a/protocols/IcqOscarJ/icqoscar8.vcxproj
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectName>ICQ</ProjectName>
- <ProjectGuid>{01DDCB36-4DE2-405D-BC36-2C8BDEB86659}</ProjectGuid>
- </PropertyGroup>
- <ImportGroup Label="PropertySheets">
- <Import Project="$(ProjectDir)..\..\build\vc.common\plugin.props" />
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/protocols/IcqOscarJ/icqoscar8.vcxproj.filters b/protocols/IcqOscarJ/icqoscar8.vcxproj.filters
deleted file mode 100644
index de5ad9f66c..0000000000
--- a/protocols/IcqOscarJ/icqoscar8.vcxproj.filters
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(ProjectDir)..\..\build\vc.common\common.filters" />
-</Project> \ No newline at end of file
diff --git a/protocols/IcqOscarJ/proto_icq/CMakeLists.txt b/protocols/IcqOscarJ/proto_icq/CMakeLists.txt
deleted file mode 100644
index 596ac21624..0000000000
--- a/protocols/IcqOscarJ/proto_icq/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-set(TARGET Proto_ICQ)
-include(${CMAKE_SOURCE_DIR}/cmake/icons.cmake) \ No newline at end of file
diff --git a/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj b/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj
deleted file mode 100644
index 1f81934ccf..0000000000
--- a/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectName>Proto_ICQ</ProjectName>
- <ProjectGuid>{DB3B0449-E576-4BBB-8B08-AB9E914D39CA}</ProjectGuid>
- </PropertyGroup>
- <ImportGroup Label="PropertySheets">
- <Import Project="$(ProjectDir)..\..\..\build\vc.common\icons.props" />
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj.filters b/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj.filters
deleted file mode 100644
index e39f86d5d6..0000000000
--- a/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj.filters
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(ProjectDir)..\..\..\build\vc.common\common.filters" />
-</Project> \ No newline at end of file
diff --git a/protocols/IcqOscarJ/proto_icq/res/Away.ico b/protocols/IcqOscarJ/proto_icq/res/Away.ico
deleted file mode 100644
index 248a3e9916..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/Away.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/proto_icq/res/DND.ico b/protocols/IcqOscarJ/proto_icq/res/DND.ico
deleted file mode 100644
index 4833160eac..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/DND.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/proto_icq/res/FFC.ico b/protocols/IcqOscarJ/proto_icq/res/FFC.ico
deleted file mode 100644
index e7ec4d3ae2..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/FFC.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/proto_icq/res/Invisible.ico b/protocols/IcqOscarJ/proto_icq/res/Invisible.ico
deleted file mode 100644
index 6a337c2926..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/Invisible.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/proto_icq/res/NA.ico b/protocols/IcqOscarJ/proto_icq/res/NA.ico
deleted file mode 100644
index ec0621dc9f..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/NA.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/proto_icq/res/Occupied.ico b/protocols/IcqOscarJ/proto_icq/res/Occupied.ico
deleted file mode 100644
index 04ea2a5855..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/Occupied.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/proto_icq/res/Offline.ico b/protocols/IcqOscarJ/proto_icq/res/Offline.ico
deleted file mode 100644
index af862168cd..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/Offline.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/proto_icq/res/Online.ico b/protocols/IcqOscarJ/proto_icq/res/Online.ico
deleted file mode 100644
index 2e33305a76..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/Online.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/proto_icq/res/Phone.ico b/protocols/IcqOscarJ/proto_icq/res/Phone.ico
deleted file mode 100644
index 74c80b66ed..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/Phone.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/proto_icq/res/Proto_ICQ.rc b/protocols/IcqOscarJ/proto_icq/res/Proto_ICQ.rc
deleted file mode 100644
index 156b8c533c..0000000000
--- a/protocols/IcqOscarJ/proto_icq/res/Proto_ICQ.rc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "..\src\resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// Russian (Russia) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
-LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE
-BEGIN
- "..\\src\\resource.h\0"
-END
-
-2 TEXTINCLUDE
-BEGIN
- "#include ""afxres.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE
-BEGIN
- "\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDI_ICON1 ICON "Offline.ico"
-IDI_ICON2 ICON "Online.ico"
-IDI_ICON3 ICON "Away.ico"
-IDI_ICON4 ICON "Invisible.ico"
-IDI_ICON5 ICON "NA.ico"
-IDI_ICON6 ICON "DND.ico"
-IDI_ICON7 ICON "Occupied.ico"
-IDI_ICON8 ICON "FFC.ico"
-IDI_ICON9 ICON "Phone.ico"
-#endif // Russian (Russia) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
diff --git a/protocols/IcqOscarJ/proto_icq/src/resource.h b/protocols/IcqOscarJ/proto_icq/src/resource.h
deleted file mode 100644
index 58048e3bc9..0000000000
--- a/protocols/IcqOscarJ/proto_icq/src/resource.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by Proto_ICQ.rc
-//
-#define IDI_ICON1 105
-#define IDI_ICON2 104
-#define IDI_ICON3 128
-#define IDI_ICON4 130
-#define IDI_ICON5 131
-#define IDI_ICON6 158
-#define IDI_ICON7 159
-#define IDI_ICON8 129
-#define IDI_ICON9 1002
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 110
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1001
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
diff --git a/protocols/IcqOscarJ/res/expandst.ico b/protocols/IcqOscarJ/res/expandst.ico
deleted file mode 100644
index a6dd1a2da9..0000000000
--- a/protocols/IcqOscarJ/res/expandst.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/IcqOscarJ/res/resources.rc b/protocols/IcqOscarJ/res/resources.rc
deleted file mode 100644
index f26bf473ba..0000000000
--- a/protocols/IcqOscarJ/res/resources.rc
+++ /dev/null
@@ -1,544 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "..\src\resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "winres.h"
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (United States) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDI_EXPANDSTRINGEDIT ICON "expandst.ico"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_ICQACCOUNT DIALOGEX 0, 0, 186, 68
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- LTEXT "ICQ Number:",IDC_STATIC,0,0,53,12
- EDITTEXT IDC_UIN,54,0,131,12,ES_AUTOHSCROLL
- LTEXT "Password:",IDC_STATIC,0,16,53,12
- EDITTEXT IDC_PW,54,16,131,12,ES_PASSWORD | ES_AUTOHSCROLL
- CONTROL "Create a new ICQ account",IDC_REGISTER,"Hyperlink",WS_TABSTOP,0,49,174,12
-END
-
-IDD_ASKAUTH DIALOGEX 0, 0, 186, 95
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Enter an authorization request"
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- DEFPUSHBUTTON "&Send",IDOK,34,74,50,14
- PUSHBUTTON "&Cancel",IDCANCEL,98,74,50,14
- EDITTEXT IDC_EDITAUTH,7,7,172,59,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN
-END
-
-IDD_LOGINPW DIALOGEX 0, 0, 157, 87
-STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Enter ICQ Password"
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- LTEXT "Enter a password for UIN %d:",IDC_INSTRUCTION,7,7,142,8
- EDITTEXT IDC_LOGINPW,17,16,122,14,ES_PASSWORD | ES_AUTOHSCROLL
- CONTROL "Remember this session password",IDC_SAVEPASS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,54,120,10
- DEFPUSHBUTTON "OK",IDOK,24,66,50,14
- PUSHBUTTON "Cancel",IDCANCEL,84,66,50,14
-END
-
-IDD_OPT_ICQ DIALOGEX 0, 0, 310, 234
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- GROUPBOX "ICQ",IDC_STICQGROUP,4,0,302,93
- RTEXT "ICQ number:",IDC_STATIC11,12,14,51,8
- EDITTEXT IDC_ICQNUM,68,12,106,12,ES_AUTOHSCROLL
- RTEXT "Password:",IDC_STATIC12,12,28,51,8
- EDITTEXT IDC_PASSWORD,68,26,106,12,ES_PASSWORD | ES_AUTOHSCROLL
- LTEXT "Hint: If you don't enter your password here, Miranda will ask for the password every time you try to go online.",IDC_STATIC,12,43,286,19
- CONTROL "Retrieve a lost password or ICQ number",IDC_LOOKUPLINK,
- "Hyperlink",WS_TABSTOP,12,78,286,8
- CONTROL "Create a new ICQ account using the ICQ website",IDC_NEWUINLINK,
- "Hyperlink",WS_TABSTOP,12,66,286,8
- GROUPBOX "Connection settings",IDC_STATIC,4,94,302,136
- LTEXT "Login Server:",IDC_STATIC,12,108,55,8
- EDITTEXT IDC_ICQSERVER,68,106,106,12,ES_AUTOHSCROLL
- LTEXT "Port:",IDC_STATIC,182,108,25,8
- EDITTEXT IDC_ICQPORT,208,106,29,12,ES_AUTOHSCROLL | ES_NUMBER
- PUSHBUTTON "Default",IDC_RESETSERVER,241,106,56,12
- LTEXT "Hint: Use port 0 to connect on a random port. Try port 80 or port 443 if you are having problems connecting through an http proxy server.",IDC_STATIC,12,120,286,18
- CONTROL "Secure Connection (SSL)",IDC_SSL,"Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,138,290,10
- CONTROL "Secure (MD5) login",IDC_MD5LOGIN,"Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,150,290,10
- CONTROL "Legacy fix (for ICQ Groupware or IServerD only)",IDC_LEGACY,
- "Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,162,290,10
- CONTROL "Send 'Keep-alives' (enable this if you use a proxy server and frequently get disconnected)",IDC_KEEPALIVE,
- "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,12,174,290,18
- CONTROL "Ignore concurrent error messages",IDC_NOERRMULTI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,192,290,10
- LTEXT "Show connection error messages:",IDC_STATIC,12,204,290,8
- CONTROL "Slider1",IDC_LOGLEVEL,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,12,216,58,10
- LTEXT "",IDC_LEVELDESCR,72,216,230,10,SS_NOPREFIX
-END
-
-IDD_OPT_ICQCONTACTS DIALOGEX 0, 0, 310, 234
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- GROUPBOX "ICQ contacts stored on server",IDC_STICQGROUP,4,0,302,97
- PUSHBUTTON "Manage server's list...",IDC_UPLOADNOW,12,77,97,14
- CONTROL "Enable server-side contact lists *",IDC_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,15,288,10
- CONTROL "Add contacts to the server's list when I add them to mine",IDC_ADDSERVER,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,33,288,10
- CONTROL "Update my contacts' details from the server *",IDC_LOADFROMSERVER,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,46,288,10
- CONTROL "Update contacts' details on the server's list when I change them in mine",IDC_SAVETOSERVER,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,59,290,10
- GROUPBOX "ICQ avatars",IDC_STATIC,4,98,302,56
- CONTROL "Enable avatar support",IDC_ENABLEAVATARS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,110,288,10
- CONTROL "Check avatar validity before saving *",IDC_STRICTAVATARCHECK,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,124,288,10
- CONTROL "Load avatars automatically (like ICQ Lite)",IDC_AUTOLOADAVATARS,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,138,288,10
- LTEXT "These changes will take effect the next time you connect to the ICQ network.",IDC_RECONNECTREQD,10,172,290,16,NOT WS_VISIBLE
- LTEXT "You cannot enable/disable the server-side contact list while you are connected to the ICQ network.",IDC_OFFLINETOENABLE,10,192,290,16,NOT WS_VISIBLE
- CTEXT "Note: The options marked with an asterisk have important side-effects or caveats that may not be initially apparent documented in the help.",IDC_STATIC,10,212,290,16
-END
-
-IDD_OPT_ICQFEATURES DIALOGEX 0, 0, 310, 200
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- GROUPBOX "Messaging",IDC_STATIC,4,0,302,56
- RTEXT "Use this codepage for Ansi <-> Unicode translation:",IDC_UTFSTATIC,12,14,174,10
- COMBOBOX IDC_UTFCODEPAGE,190,12,107,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- CONTROL "Make me temporarily visible to contacts I send message to",IDC_TEMPVISIBLE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,29,288,10
- CONTROL "Notify me when a message delivery has failed",IDC_SLOWSEND,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,41,288,10
- GROUPBOX "Peer-to-peer Messaging",IDC_STATIC,4,59,302,41
- CONTROL "Enable peer-to-peer message connections",IDC_DCENABLE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,72,288,10
- CONTROL "Passive mode (i.e., do not initiate new connections)",IDC_DCPASSIVE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,84,288,10
- GROUPBOX "Extra Features",IDC_STATIC,4,103,302,79
- CONTROL "Enable Custom status support for xtraz",IDC_XSTATUSENABLE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,115,288,10
- CONTROL "Enable Custom status support for moods",IDC_MOODSENABLE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,127,288,10
- CONTROL "Reset Custom status on status change",IDC_XSTATUSRESET,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,140,288,10
- CONTROL "Auto-retrieve Custom status details",IDC_XSTATUSAUTO,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,153,288,10
- CONTROL "Block known Spam Bots",IDC_KILLSPAMBOTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,166,288,10
-END
-
-IDD_OPT_ICQPRIVACY DIALOGEX 0, 0, 310, 234
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- GROUPBOX "Direct connections",IDC_STATIC_DC1,4,0,302,78
- LTEXT "Allowing direct connections will expose your IP address but may be necessary for some ICQ features to work properly.",IDC_STATIC_DC2,10,12,292,17
- CONTROL "Allow direct connections with any user",IDC_DCALLOW_ANY,
- "Button",BS_AUTORADIOBUTTON,21,34,281,10
- CONTROL "Allow direct connections with users on my contact list",IDC_DCALLOW_CLIST,
- "Button",BS_AUTORADIOBUTTON,21,47,281,10
- CONTROL "Allow direct connections only when I authorize or initiate them",IDC_DCALLOW_AUTH,
- "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,21,60,281,10
- GROUPBOX "Contact List Authorization",IDC_STATIC_CLIST,4,83,302,45,WS_GROUP
- CONTROL "All users may add me to their Contact List",IDC_ADD_ANY,
- "Button",BS_AUTORADIOBUTTON,21,97,281,10
- CONTROL "I want to be asked when someone wants to add me to their Contact List",IDC_ADD_AUTH,
- "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,21,111,281,10
- GROUPBOX "Misc Settings",IDC_STATIC,4,131,302,78
- CONTROL "Allow others to view my Online / Offline status from the web (Web Aware)",IDC_WEBAWARE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,144,281,10
- CONTROL "Allow others to view my primary e-mail address",IDC_PUBLISHPRIMARY,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,160,281,10
- CONTROL "Only reply to status message requests from users on my contact list",IDC_STATUSMSG_CLIST,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,176,281,10
- CONTROL "Only reply to status message request from visible contacts",IDC_STATUSMSG_VISIBLE,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,33,192,269,10
- CTEXT "Some options are grayed out because they can only be changed when you are online.",IDC_STATIC_NOTONLINE,4,215,302,8
-END
-
-IDD_OPT_POPUPS DIALOGEX 0, 0, 314, 251
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- GROUPBOX "Options",IDC_STATIC,4,4,305,71
- CONTROL "Enable popup support",IDC_POPUPS_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,19,216,10
- CONTROL "Display errors using popups",IDC_POPUPS_LOG_ENABLED,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,37,216,10
- CONTROL "Display popup when spambot is detected",IDC_POPUPS_SPAM_ENABLED,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,50,216,10
- GROUPBOX "Look && Feel",IDC_STATIC,4,80,305,160
- LTEXT "Back Color",IDC_STATIC,80,93,42,8
- LTEXT "Text Color",IDC_STATIC,130,93,40,8
- LTEXT "Timeout",IDC_STATIC,182,93,60,8
- LTEXT "Note",IDC_STATIC,12,105,60,8
- CONTROL "",IDC_POPUP_LOG0_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,104,39,10
- CONTROL "",IDC_POPUP_LOG0_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,104,39,10
- EDITTEXT IDC_POPUP_LOG0_TIMEOUT,182,103,34,12,ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "Warning",IDC_STATIC,12,120,60,8
- CONTROL "",IDC_POPUP_LOG1_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,119,39,10
- CONTROL "",IDC_POPUP_LOG1_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,119,39,10
- EDITTEXT IDC_POPUP_LOG1_TIMEOUT,182,118,34,12,ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "Error",IDC_STATIC,12,135,60,8
- CONTROL "",IDC_POPUP_LOG2_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,134,39,10
- CONTROL "",IDC_POPUP_LOG2_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,134,39,10
- EDITTEXT IDC_POPUP_LOG2_TIMEOUT,182,133,34,12,ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "Fatal",IDC_STATIC,12,150,60,8
- CONTROL "",IDC_POPUP_LOG3_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,149,39,10
- CONTROL "",IDC_POPUP_LOG3_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,149,39,10
- EDITTEXT IDC_POPUP_LOG3_TIMEOUT,182,148,34,12,ES_AUTOHSCROLL | ES_NUMBER
- LTEXT "Spam detected",IDC_STATIC,12,165,60,8
- CONTROL "",IDC_POPUP_SPAM_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,164,39,10
- CONTROL "",IDC_POPUP_SPAM_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,164,39,10
- EDITTEXT IDC_POPUP_SPAM_TIMEOUT,182,163,34,12,ES_AUTOHSCROLL | ES_NUMBER
- CONTROL "&Use Windows colors",IDC_USEWINCOLORS,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,12,183,220,8
- CONTROL "Use system &icons",IDC_USESYSICONS,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,12,211,220,8
- DEFPUSHBUTTON "Previe&w",IDC_PREVIEW,247,192,52,12
- CONTROL "Use default colors",IDC_USEDEFCOLORS,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,12,196,221,10
-END
-
-IDD_INFO_ICQ DIALOGEX 0, 0, 222, 132
-STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- LTEXT "UIN:",IDC_UINSTATIC,5,5,71,8
- EDITTEXT IDC_UIN,74,5,143,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
- LTEXT "External IP:",IDC_STATIC,5,18,71,8
- EDITTEXT IDC_IP,74,18,74,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
- LTEXT "Internal IP:",IDC_STATIC,5,31,71,8
- EDITTEXT IDC_REALIP,74,31,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
- LTEXT "Port:",IDC_STATIC,5,44,71,8
- EDITTEXT IDC_PORT,74,44,141,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
- LTEXT "Protocol Version:",IDC_STATIC,5,57,71,8
- EDITTEXT IDC_VERSION,74,57,142,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
- LTEXT "User Client:",IDC_STATIC,5,70,71,8
- EDITTEXT IDC_MIRVER,74,70,141,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
- LTEXT "Online since:",IDC_STATIC,5,83,71,8
- EDITTEXT IDC_ONLINESINCE,74,83,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
- LTEXT "System up since:",IDC_SUPTIME,5,96,71,8
- EDITTEXT IDC_SYSTEMUPTIME,74,96,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
- LTEXT "Idle since:",IDC_STATIC,5,109,71,8
- EDITTEXT IDC_IDLETIME,74,109,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
- LTEXT "Status:",IDC_STATIC,5,122,71,8
- EDITTEXT IDC_STATUS,74,122,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
-END
-
-IDD_ICQADVANCEDSEARCH DIALOGEX 0, 0, 335, 247
-STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_BORDER
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- GROUPBOX "Summary",IDC_SUMMARYGROUP,8,3,156,131
- LTEXT "Nickname:",IDC_STATIC,15,14,50,8
- EDITTEXT IDC_NICK,65,12,91,12,ES_AUTOHSCROLL
- LTEXT "First name:",IDC_STATIC,15,29,50,8
- EDITTEXT IDC_FIRSTNAME,65,27,91,12,ES_AUTOHSCROLL
- LTEXT "Last name:",IDC_STATIC,15,44,50,8
- EDITTEXT IDC_LASTNAME,65,42,91,12,ES_AUTOHSCROLL
- LTEXT "E-mail:",IDC_STATIC,15,59,50,8
- EDITTEXT IDC_EMAIL,65,57,91,12,ES_AUTOHSCROLL
- LTEXT "Gender:",IDC_STATIC,15,74,50,8
- COMBOBOX IDC_GENDER,65,72,91,51,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- LTEXT "Age:",IDC_STATIC,15,89,50,8
- COMBOBOX IDC_AGERANGE,65,87,91,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "Marital status:",IDC_STATIC,15,104,50,8
- COMBOBOX IDC_MARITALSTATUS,65,102,91,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "Keywords:",IDC_STATIC,15,119,50,8
- EDITTEXT IDC_KEYWORDS,65,117,91,12,ES_AUTOHSCROLL
- GROUPBOX "Work",IDC_WORKGROUP,8,138,156,102
- LTEXT "Occupation:",IDC_STATIC,15,149,50,8
- COMBOBOX IDC_WORKFIELD,65,147,91,93,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- LTEXT "Company:",IDC_STATIC,15,164,50,8
- EDITTEXT IDC_COMPANY,65,162,91,12,ES_AUTOHSCROLL
- LTEXT "Department:",IDC_STATIC,15,179,50,8
- EDITTEXT IDC_DEPARTMENT,65,177,91,12,ES_AUTOHSCROLL
- LTEXT "Position:",IDC_STATIC,15,194,50,8
- EDITTEXT IDC_POSITION,65,192,91,12,ES_AUTOHSCROLL
- LTEXT "Organization:",IDC_STATIC,15,209,50,8
- COMBOBOX IDC_ORGANISATION,65,207,91,99,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- LTEXT "Keywords:",IDC_STATIC,24,224,41,8
- EDITTEXT IDC_ORGKEYWORDS,65,222,91,12,ES_AUTOHSCROLL
- GROUPBOX "Location",IDC_LOCATIONGROUP,171,3,156,72
- LTEXT "Language:",IDC_STATIC,178,14,50,8
- COMBOBOX IDC_LANGUAGE,228,12,91,113,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- LTEXT "Country:",IDC_STATIC,178,29,50,8
- COMBOBOX IDC_COUNTRY,228,27,91,172,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- LTEXT "State:",IDC_STATIC,178,44,50,8
- EDITTEXT IDC_STATE,228,42,91,12,ES_AUTOHSCROLL
- LTEXT "City:",IDC_STATIC,178,59,50,8
- EDITTEXT IDC_CITY,228,57,91,12,ES_AUTOHSCROLL
- GROUPBOX "Background info",IDC_BACKGROUNDGROUP,171,79,156,116
- LTEXT "Interests",IDC_STATIC,178,90,50,8
- LTEXT "Category:",IDC_STATIC,188,101,40,8
- COMBOBOX IDC_INTERESTSCAT,228,99,91,95,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- LTEXT "Keywords:",IDC_STATIC,188,116,40,8
- EDITTEXT IDC_INTERESTSKEY,228,114,91,12,ES_AUTOHSCROLL
- LTEXT "Past",IDC_STATIC,178,129,50,8
- LTEXT "Category:",IDC_STATIC,188,140,40,8
- COMBOBOX IDC_PASTCAT,228,138,91,97,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
- LTEXT "Keywords:",IDC_STATIC,188,155,40,8
- EDITTEXT IDC_PASTKEY,228,153,91,12,ES_AUTOHSCROLL
- LTEXT "Homepage",IDC_STATIC,178,168,50,8
- LTEXT "Category:",IDC_STATIC,188,179,40,8,NOT WS_VISIBLE
- COMBOBOX IDC_HOMEPAGECAT,228,177,91,56,CBS_DROPDOWNLIST | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
- LTEXT "Keywords:",IDC_STATIC,188,179,40,8
- EDITTEXT IDC_HOMEPAGEKEY,228,177,91,12,ES_AUTOHSCROLL
- GROUPBOX "Other",IDC_OTHERGROUP,171,199,156,41
- CONTROL "Search online users only",IDC_ONLINEONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,217,142,10
-END
-
-IDD_ICQUPLOADLIST DIALOGEX 0, 0, 358, 241
-STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
-EXSTYLE WS_EX_CONTROLPARENT
-CAPTION "Manage ICQ Server Contacts"
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- LTEXT "Select contacts to store:",IDC_STATIC11,5,5,91,8
- CONTROL "",IDC_CLIST,"CListControl",WS_TABSTOP | 0x3da,5,14,155,222,WS_EX_CLIENTEDGE
- DEFPUSHBUTTON "Synchronize",IDOK,226,222,68,14
- PUSHBUTTON "Cancel",IDCANCEL,298,222,55,14
- LISTBOX IDC_LOG,169,5,184,213,NOT LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL | WS_TABSTOP
-END
-
-IDD_SETXSTATUS DIALOGEX 0, 0, 189, 98
-STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
-EXSTYLE WS_EX_CONTROLPARENT
-CAPTION "Custom Status ""%s"" Details"
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- DEFPUSHBUTTON "Closing in %d",IDOK,62,79,65,14
- LTEXT "Title:",IDC_XTITLE_STATIC,5,0,179,8
- EDITTEXT IDC_XTITLE,5,9,179,13,ES_AUTOHSCROLL
- LTEXT "Message:",IDC_XMSG_STATIC,5,22,179,8
- EDITTEXT IDC_XMSG,5,31,179,43,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
- CTEXT "Retrieving custom status details...",IDC_RETRXSTATUS,5,0,179,75,SS_CENTERIMAGE | NOT WS_VISIBLE
-END
-
-IDD_INFO_CHANGEINFO DIALOGEX 0, 0, 222, 132
-STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,2,2,218,113
- PUSHBUTTON "&Save changes",IDC_SAVE,140,117,80,13,WS_DISABLED
- EDITTEXT IDC_UPLOADING,2,118,127,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_VISIBLE | NOT WS_BORDER
-END
-
-IDD_PWCONFIRM DIALOGEX 0, 0, 167, 78
-STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
-EXSTYLE WS_EX_CONTROLPARENT
-CAPTION "Confirm Password Change"
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- LTEXT "Please re-type your new password:",IDC_STATIC,5,5,157,9
- EDITTEXT IDC_PASSWORD,5,15,157,12,ES_PASSWORD | ES_AUTOHSCROLL
- LTEXT "Enter your current password:",IDC_STATIC,5,32,157,9
- EDITTEXT IDC_OLDPASS,5,42,157,12,ES_PASSWORD | ES_AUTOHSCROLL
- DEFPUSHBUTTON "OK",IDOK,26,59,50,14
- PUSHBUTTON "Cancel",IDCANCEL,91,59,50,14
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
-BEGIN
- IDD_ICQACCOUNT, DIALOG
- BEGIN
- LEFTMARGIN, 7
- TOPMARGIN, 7
- END
-
- IDD_ASKAUTH, DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 179
- TOPMARGIN, 7
- BOTTOMMARGIN, 88
- END
-
- IDD_LOGINPW, DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 149
- TOPMARGIN, 7
- BOTTOMMARGIN, 80
- END
-
- IDD_OPT_ICQ, DIALOG
- BEGIN
- LEFTMARGIN, 4
- VERTGUIDE, 12
- VERTGUIDE, 174
- VERTGUIDE, 302
- TOPMARGIN, 4
- HORZGUIDE, 120
- END
-
- IDD_OPT_ICQCONTACTS, DIALOG
- BEGIN
- LEFTMARGIN, 4
- VERTGUIDE, 12
- VERTGUIDE, 302
- TOPMARGIN, 4
- BOTTOMMARGIN, 232
- END
-
- IDD_OPT_ICQFEATURES, DIALOG
- BEGIN
- LEFTMARGIN, 4
- VERTGUIDE, 12
- TOPMARGIN, 7
- END
-
- IDD_OPT_ICQPRIVACY, DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 307
- TOPMARGIN, 7
- BOTTOMMARGIN, 233
- END
-
- IDD_OPT_POPUPS, DIALOG
- BEGIN
- LEFTMARGIN, 4
- RIGHTMARGIN, 309
- VERTGUIDE, 12
- VERTGUIDE, 80
- VERTGUIDE, 130
- VERTGUIDE, 182
- TOPMARGIN, 4
- HORZGUIDE, 19
- HORZGUIDE, 37
- HORZGUIDE, 104
- HORZGUIDE, 203
- END
-
- IDD_INFO_ICQ, DIALOG
- BEGIN
- LEFTMARGIN, 5
- RIGHTMARGIN, 217
- VERTGUIDE, 61
- TOPMARGIN, 5
- BOTTOMMARGIN, 129
- HORZGUIDE, 22
- HORZGUIDE, 35
- HORZGUIDE, 48
- HORZGUIDE, 61
- HORZGUIDE, 74
- END
-
- IDD_ICQADVANCEDSEARCH, DIALOG
- BEGIN
- LEFTMARGIN, 8
- RIGHTMARGIN, 327
- VERTGUIDE, 15
- VERTGUIDE, 25
- VERTGUIDE, 65
- VERTGUIDE, 156
- VERTGUIDE, 178
- VERTGUIDE, 228
- VERTGUIDE, 319
- TOPMARGIN, 5
- BOTTOMMARGIN, 239
- END
-
- IDD_ICQUPLOADLIST, DIALOG
- BEGIN
- LEFTMARGIN, 5
- RIGHTMARGIN, 353
- TOPMARGIN, 5
- BOTTOMMARGIN, 236
- END
-
- IDD_INFO_CHANGEINFO, DIALOG
- BEGIN
- LEFTMARGIN, 2
- RIGHTMARGIN, 220
- TOPMARGIN, 2
- BOTTOMMARGIN, 130
- END
-
- IDD_PWCONFIRM, DIALOG
- BEGIN
- LEFTMARGIN, 5
- RIGHTMARGIN, 162
- TOPMARGIN, 5
- BOTTOMMARGIN, 73
- END
-END
-#endif // APSTUDIO_INVOKED
-
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE
-BEGIN
- "..\\src\\resource.h\0"
-END
-
-2 TEXTINCLUDE
-BEGIN
- "#include ""winres.h""\0"
-END
-
-3 TEXTINCLUDE
-BEGIN
- "\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-#endif // English (United States) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
diff --git a/protocols/IcqOscarJ/res/version.rc b/protocols/IcqOscarJ/res/version.rc
deleted file mode 100644
index 5a5ddd63ed..0000000000
--- a/protocols/IcqOscarJ/res/version.rc
+++ /dev/null
@@ -1,9 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#ifdef APSTUDIO_INVOKED
-#error this file is not editable by Microsoft Visual C++
-#endif //APSTUDIO_INVOKED
-
-#include "..\src\version.h"
-
-#include "..\..\build\Version.rc"
diff --git a/protocols/IcqOscarJ/src/askauthentication.cpp b/protocols/IcqOscarJ/src/askauthentication.cpp
deleted file mode 100644
index 1afcac4f89..0000000000
--- a/protocols/IcqOscarJ/src/askauthentication.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-class AskAuthProcDlg : public CProtoDlgBase<CIcqProto>
-{
- MCONTACT m_hContact;
-
- CCtrlEdit m_auth;
- CCtrlButton m_btnOk;
-
-public:
- AskAuthProcDlg(CIcqProto *_ppro, MCONTACT _hContact) :
- CProtoDlgBase<CIcqProto>(_ppro, IDD_ASKAUTH),
- m_hContact(_hContact),
- m_auth(this, IDC_EDITAUTH),
- m_btnOk(this, IDOK)
- {
- m_autoClose = CLOSE_ON_CANCEL; // let onOk() to close window manually
- m_btnOk.OnClick = Callback(this, &AskAuthProcDlg::onOk);
- }
-
- bool OnInitDialog() override
- {
- if (!m_hContact || !m_proto->icqOnline())
- EndDialog(m_hwnd, 0);
-
- m_auth.SendMsg(EM_LIMITTEXT, 255, 0);
- m_auth.SetText(TranslateT("Please authorize me to add you to my contact list."));
- return true;
- }
-
- void onOk(CCtrlButton*)
- {
- if (!m_proto->icqOnline())
- return;
-
- DWORD dwUin;
- uid_str szUid;
- if (m_proto->getContactUid(m_hContact, &dwUin, &szUid))
- return; // Invalid contact
-
- char *szReason = GetWindowTextUtf(m_auth.GetHwnd());
- m_proto->icq_sendAuthReqServ(dwUin, szUid, szReason);
- SAFE_FREE((void**)&szReason);
-
- // auth bug fix (thx Bio)
- if (m_proto->m_bSsiEnabled && dwUin)
- m_proto->resetServContactAuthState(m_hContact);
-
- EndDialog(m_hwnd, 0);
- }
-};
-
-INT_PTR CIcqProto::RequestAuthorization(WPARAM wParam, LPARAM)
-{
- AskAuthProcDlg(this, wParam).DoModal();
- return 0;
-}
diff --git a/protocols/IcqOscarJ/src/capabilities.cpp b/protocols/IcqOscarJ/src/capabilities.cpp
deleted file mode 100644
index bdde98f6d8..0000000000
--- a/protocols/IcqOscarJ/src/capabilities.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Contains helper functions to handle oscar user capabilities. Scanning and
-// adding capabilities are assumed to be more timecritical than looking up
-// capabilites. During the login sequence there could possibly be many hundred
-// scans but only a few lookups. So when you add or change something in this
-// code you must have this in mind, dont do anything that will slow down the
-// adding process too much.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-struct icq_capability
-{
- DWORD capID; // A bitmask, we use it in order to save database space
- capstr capCLSID; // A binary representation of a oscar capability
-};
-
-static const icq_capability CapabilityRecord[] =
-{
- { CAPF_SRV_RELAY, { CAP_SRV_RELAY }},
- { CAPF_UTF, { CAP_UTF }},
- { CAPF_RTF, { CAP_RTF }},
- { CAPF_CONTACTS, { CAP_CONTACTS }},
- { CAPF_TYPING, { CAP_TYPING }},
- { CAPF_ICQDIRECT, { CAP_ICQDIRECT }},
- { CAPF_XTRAZ, { CAP_XTRAZ }},
- { CAPF_OSCAR_FILE, { CAP_OSCAR_FILE }}
-};
-
-// Mask of all handled capabilities' flags
-#define CapabilityFlagsMask (CAPF_SRV_RELAY | CAPF_UTF | CAPF_RTF | CAPF_CONTACTS | CAPF_TYPING | CAPF_ICQDIRECT | CAPF_XTRAZ | CAPF_OSCAR_FILE)
-
-
-#ifdef _DEBUG
-struct icq_capability_name
-{
- DWORD capID;
- const char* capName;
-};
-
-static const icq_capability_name CapabilityNames[] =
-{
- { CAPF_SRV_RELAY, "ServerRelay"},
- { CAPF_UTF, "UTF8 Messages"},
- { CAPF_RTF, "RTF Messages"},
- { CAPF_CONTACTS, "Contact Transfer"},
- { CAPF_TYPING, "Typing Notifications"},
- { CAPF_ICQDIRECT, "Direct Connections"},
- { CAPF_XTRAZ, "Xtraz"},
- { CAPF_OSCAR_FILE, "File Transfers"},
- { CAPF_STATUS_MESSAGES,"Individual Status Messages"},
- { CAPF_STATUS_MOOD, "Mood"},
- { CAPF_XSTATUS, "Custom Status"}
-};
-
-void NetLog_CapabilityChange(CIcqProto *ppro, const char *szChange, DWORD fdwCapabilities)
-{
- char szBuffer[MAX_PATH] = { 0 };
-
- if (!fdwCapabilities) return;
-
- for (auto &it : CapabilityNames) {
- // Check if the current capability is present
- if ((fdwCapabilities & it.capID) == it.capID) {
- if (mir_strlen(szBuffer))
- mir_strcat(szBuffer, ", ");
- mir_strcat(szBuffer, it.capName);
- }
- }
- // Log the change
- ppro->debugLogA("Capabilities: %s %s", szChange, szBuffer);
-}
-#endif
-
-// Deletes all oscar capabilities for a given contact
-void CIcqProto::ClearAllContactCapabilities(MCONTACT hContact)
-{
- setDword(hContact, DBSETTING_CAPABILITIES, 0);
-}
-
-// Deletes one or many oscar capabilities for a given contact
-void CIcqProto::ClearContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities)
-{
- // Get current capability flags
- DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0);
- if (fdwContactCaps != (fdwContactCaps & ~fdwCapabilities)) {
-#ifdef _DEBUG
- NetLog_CapabilityChange(this, "Removed", fdwCapabilities & fdwContactCaps);
-#endif
- // Clear unwanted capabilities
- fdwContactCaps &= ~fdwCapabilities;
-
- // And write it back to disk
- setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps);
- }
-}
-
-// Sets one or many oscar capabilities for a given contact
-void CIcqProto::SetContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities)
-{
- // Get current capability flags
- DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0);
- if (fdwContactCaps != (fdwContactCaps | fdwCapabilities)) {
-#ifdef _DEBUG
- NetLog_CapabilityChange(this, "Added", fdwCapabilities & ~fdwContactCaps);
-#endif
- // Update them
- fdwContactCaps |= fdwCapabilities;
-
- // And write it back to disk
- setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps);
- }
-}
-
-// Returns true if the given contact supports the requested capabilites
-BOOL CIcqProto::CheckContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities)
-{
- // Get current capability flags
- DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0);
-
- // Check if all requested capabilities are supported
- if ((fdwContactCaps & fdwCapabilities) == fdwCapabilities)
- return TRUE;
-
- return FALSE;
-}
-
-
-// Scan capability against the capability buffer
-capstr* MatchCapability(BYTE *buf, size_t bufsize, const capstr *cap, size_t capsize)
-{
- while (bufsize >= BINARY_CAP_SIZE) { // search the buffer for a capability
- if (!memcmp(buf, cap, capsize))
- return (capstr*)buf; // give found capability for version info
-
- buf += BINARY_CAP_SIZE;
- bufsize -= BINARY_CAP_SIZE;
- }
- return nullptr;
-}
-
-
-// Scan short capability against the capability buffer
-capstr* MatchShortCapability(BYTE *buf, size_t bufsize, const shortcapstr *cap)
-{
- capstr fullCap;
- memcpy(fullCap, capShortCaps, BINARY_CAP_SIZE);
- fullCap[2] = (*cap)[0];
- fullCap[3] = (*cap)[1];
-
- return MatchCapability(buf, bufsize, &fullCap, BINARY_CAP_SIZE);
-}
-
-// Scans a binary buffer for OSCAR capabilities.
-DWORD GetCapabilitiesFromBuffer(BYTE *pBuffer, int nLength)
-{
- DWORD fdwCaps = 0;
-
- // Calculate the number of records
- int nRecordSize = _countof(CapabilityRecord);
-
- // Loop over all capabilities in the buffer and
- // compare them to our own record of capabilities
- for (int nIndex = 0; nIndex < nRecordSize; nIndex++) {
- // Match, add capability flag
- if (MatchCapability(pBuffer, nLength, &CapabilityRecord[nIndex].capCLSID, BINARY_CAP_SIZE))
- fdwCaps |= CapabilityRecord[nIndex].capID;
- }
-
- return fdwCaps;
-}
-
-// Scans a binary buffer for oscar capabilities and adds them to the contact.
-// You probably want to call ClearAllContactCapabilities() first.
-void CIcqProto::AddCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength)
-{
- // Get current capability flags
- DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0);
- // Get capability flags from buffer
- DWORD fdwCapabilities = GetCapabilitiesFromBuffer(pBuffer, nLength);
-
- if (fdwContactCaps != (fdwContactCaps | fdwCapabilities)) {
-#ifdef _DEBUG
- NetLog_CapabilityChange(this, "Added", fdwCapabilities & ~fdwContactCaps);
-#endif
- // Add capability flags from buffer
- fdwContactCaps |= fdwCapabilities;
-
- // And write them back to database
- setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps);
- }
-}
-
-// Scans a binary buffer for oscar capabilities and adds them to the contact.
-// You probably want to call ClearAllContactCapabilities() first.
-void CIcqProto::SetCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength, BOOL bReset)
-{
- // Get current capability flags
- DWORD fdwContactCaps = bReset ? 0 : getDword(hContact, DBSETTING_CAPABILITIES, 0);
- // Get capability flags from buffer
- DWORD fdwCapabilities = GetCapabilitiesFromBuffer(pBuffer, nLength);
-
-#ifdef _DEBUG
- if (bReset)
- NetLog_CapabilityChange(this, "Set", fdwCapabilities);
- else {
- NetLog_CapabilityChange(this, "Removed", fdwContactCaps & ~fdwCapabilities & CapabilityFlagsMask);
- NetLog_CapabilityChange(this, "Added", fdwCapabilities & ~fdwContactCaps);
- }
-#endif
-
- if (fdwCapabilities != (fdwContactCaps & ~CapabilityFlagsMask)) {
- // Get current unmanaged capability flags
- fdwContactCaps &= ~CapabilityFlagsMask;
-
- // Add capability flags from buffer
- fdwContactCaps |= fdwCapabilities;
-
- // And write them back to database
- setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps);
- }
-}
diff --git a/protocols/IcqOscarJ/src/capabilities.h b/protocols/IcqOscarJ/src/capabilities.h
deleted file mode 100644
index 860c33fcc8..0000000000
--- a/protocols/IcqOscarJ/src/capabilities.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Contains helper functions to handle OSCAR user capabilities.
-// -----------------------------------------------------------------------------
-
-#ifndef __CAPABILITIES_H
-#define __CAPABILITIES_H
-
-// capabilities
-typedef BYTE capstr[BINARY_CAP_SIZE];
-typedef BYTE shortcapstr[BINARY_SHORT_CAP_SIZE];
-
-extern const capstr capShortCaps;
-
-capstr* MatchCapability(BYTE *buf, size_t bufsize, const capstr *cap, size_t capsize = BINARY_CAP_SIZE);
-capstr* MatchShortCapability(BYTE *buf, size_t bufsize, const shortcapstr *cap);
-
-
-#endif /* __CAPABILITIES_H */
diff --git a/protocols/IcqOscarJ/src/chan_01login.cpp b/protocols/IcqOscarJ/src/chan_01login.cpp
deleted file mode 100644
index 9f7f99f755..0000000000
--- a/protocols/IcqOscarJ/src/chan_01login.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleLoginChannel(BYTE*, size_t, serverthread_info *info)
-{
- icq_packet packet;
-
- debugLogA("Received SRV_HELLO from %s", info->isLoginServer ? "login server" : "communication server");
-
- // isLoginServer is "1" if we just received SRV_HELLO
- if (info->isLoginServer) {
- if (m_bSecureLogin) {
- debugLogA("Sending %s to %s", "CLI_HELLO", "login server");
-
- packet.wLen = 12;
- write_flap(&packet, ICQ_LOGIN_CHAN);
- packDWord(&packet, 0x00000001);
- packTLVDWord(&packet, 0x8003, 0x00100000); // unknown
- sendServPacket(&packet); // greet login server
-
- char szUin[UINMAXLEN];
- size_t wUinLen = mir_strlen(strUID(m_dwLocalUIN, szUin));
-
- debugLogA("Sending %s to %s", "ICQ_SIGNON_AUTH_REQUEST", "login server");
-
- serverPacketInit(&packet, 14 + wUinLen);
- packFNACHeader(&packet, ICQ_AUTHORIZATION_FAMILY, ICQ_SIGNON_AUTH_REQUEST, 0, 0);
- packTLV(&packet, 0x0001, wUinLen, (LPBYTE)szUin);
- sendServPacket(&packet); // request login digest
- }
- else {
- sendClientAuth((char*)info->szAuthKey, info->wAuthKeyLen, FALSE);
- debugLogA("Sent CLI_IDENT to %s", "login server");
- }
-
- info->isLoginServer = false;
- if (info->cookieDataLen) {
- SAFE_FREE((void**)&info->cookieData);
- info->cookieDataLen = 0;
- }
- }
- else {
- if (info->cookieDataLen) {
- wLocalSequence = generate_flap_sequence();
-
- serverCookieInit(&packet, info->cookieData, info->cookieDataLen);
- sendServPacket(&packet);
-
- debugLogA("Sent CLI_IDENT to %s", "communication server");
-
- SAFE_FREE((void**)&info->cookieData);
- info->cookieDataLen = 0;
- }
- else // We need a cookie to identify us to the communication server
- debugLogA("Error: Connected to %s without a cookie!", "communication server");
- }
-}
diff --git a/protocols/IcqOscarJ/src/chan_02data.cpp b/protocols/IcqOscarJ/src/chan_02data.cpp
deleted file mode 100644
index d330af877b..0000000000
--- a/protocols/IcqOscarJ/src/chan_02data.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Handle channel 2 (Data) packets
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleDataChannel(BYTE *pBuffer, size_t wBufferLength, serverthread_info *info)
-{
- snac_header snacHeader = {0};
-
- if (!unpackSnacHeader(&snacHeader, &pBuffer, &wBufferLength) || !snacHeader.bValid)
- debugLogA("Error: Failed to parse SNAC header");
- else {
- if (snacHeader.wFlags & 0x8000)
- debugLogA(" Received SNAC(x%02X,x%02X), version %u", snacHeader.wFamily, snacHeader.wSubtype, snacHeader.wVersion);
- else
- debugLogA(" Received SNAC(x%02X,x%02X)", snacHeader.wFamily, snacHeader.wSubtype);
-
- switch (snacHeader.wFamily) {
-
- case ICQ_SERVICE_FAMILY:
- handleServiceFam(pBuffer, wBufferLength, &snacHeader, info);
- break;
-
- case ICQ_LOCATION_FAMILY:
- handleLocationFam(pBuffer, wBufferLength, &snacHeader);
- break;
-
- case ICQ_BUDDY_FAMILY:
- handleBuddyFam(pBuffer, wBufferLength, &snacHeader, info);
- break;
-
- case ICQ_MSG_FAMILY:
- handleMsgFam(pBuffer, wBufferLength, &snacHeader);
- break;
-
- case ICQ_BOS_FAMILY:
- handleBosFam(pBuffer, wBufferLength, &snacHeader);
- break;
-
- case ICQ_LOOKUP_FAMILY:
- handleLookupFam(pBuffer, wBufferLength, &snacHeader);
- break;
-
- case ICQ_STATS_FAMILY:
- handleStatusFam(pBuffer, wBufferLength, &snacHeader);
- break;
-
- case ICQ_LISTS_FAMILY:
- handleServCListFam(pBuffer, wBufferLength, &snacHeader, info);
- break;
-
- case ICQ_EXTENSIONS_FAMILY:
- handleIcqExtensionsFam(pBuffer, wBufferLength, &snacHeader);
- break;
-
- case ICQ_AUTHORIZATION_FAMILY:
- handleAuthorizationFam(pBuffer, wBufferLength, &snacHeader, info);
- break;
-
- default:
- debugLogA("Ignoring SNAC(x%02X,x%02X) - FAMILYx%02X not implemented", snacHeader.wFamily, snacHeader.wSubtype, snacHeader.wFamily);
- break;
- }
- }
-}
-
-
-int unpackSnacHeader(snac_header *pSnacHeader, BYTE **pBuffer, size_t *pwBufferLength)
-{
- WORD wRef1, wRef2;
-
- // Check header
- if (!pSnacHeader)
- return 0;
-
- // 10 bytes is the minimum size of a header
- if (*pwBufferLength < 10) {
- // Buffer overflow
- pSnacHeader->bValid = FALSE;
- return 1;
- }
-
- // Unpack all the standard data
- unpackWord(pBuffer, &(pSnacHeader->wFamily));
- unpackWord(pBuffer, &(pSnacHeader->wSubtype));
- unpackWord(pBuffer, &(pSnacHeader->wFlags));
- unpackWord(pBuffer, &wRef1); // unpack reference id (sequence)
- unpackWord(pBuffer, &wRef2); // command
- pSnacHeader->dwRef = wRef1 | (wRef2 << 0x10);
-
- *pwBufferLength -= 10;
-
- // If flag bit 15 is set, we also have a version tag
- // (...at least that is what I think it is)
- if (pSnacHeader->wFlags & 0x8000) {
- if (*pwBufferLength >= 2) {
- WORD wExtraBytes = 0;
-
- unpackWord(pBuffer, &wExtraBytes);
- *pwBufferLength -= 2;
-
- if (*pwBufferLength >= wExtraBytes) {
- if (wExtraBytes == 6) {
- *pBuffer += 4; // TLV type and length?
- unpackWord(pBuffer, &(pSnacHeader->wVersion));
- *pwBufferLength -= wExtraBytes;
- pSnacHeader->bValid = TRUE;
- }
- else if (wExtraBytes == 0x0E) {
- *pBuffer += 8; // TLV(2) - unknown
- *pBuffer += 4;
- unpackWord(pBuffer, &(pSnacHeader->wVersion));
- *pwBufferLength -= wExtraBytes;
- pSnacHeader->bValid = TRUE;
- }
- else {
- *pBuffer += wExtraBytes;
- *pwBufferLength -= wExtraBytes;
- pSnacHeader->bValid = TRUE;
- }
- }
- else // Buffer overflow
- pSnacHeader->bValid = FALSE;
- }
- else // Buffer overflow
- pSnacHeader->bValid = FALSE;
- }
- else pSnacHeader->bValid = TRUE;
-
- return 1;
-}
-
-
-void CIcqProto::LogFamilyError(WORD wFamily, WORD wError)
-{
- char *msg;
-
- switch (wError) {
- case 0x01: msg = "Invalid SNAC header"; break;
- case 0x02: msg = "Server rate limit exceeded"; break;
- case 0x03: msg = "Client rate limit exceeded"; break;
- case 0x04: msg = "Recipient is not logged in"; break;
- case 0x05: msg = "Requested service unavailable"; break;
- case 0x06: msg = "Requested service not defined"; break;
- case 0x07: msg = "You sent obsolete SNAC"; break;
- case 0x08: msg = "Not supported by server"; break;
- case 0x09: msg = "Not supported by client"; break;
- case 0x0A: msg = "Refused by client"; break;
- case 0x0B: msg = "Reply too big"; break;
- case 0x0C: msg = "Responses lost"; break;
- case 0x0D: msg = "Request denied"; break;
- case 0x0E: msg = "Incorrect SNAC format"; break;
- case 0x0F: msg = "Insufficient rights"; break;
- case 0x10: msg = "In local permit/deny (recipient blocked)"; break;
- case 0x11: msg = "Sender is too evil"; break;
- case 0x12: msg = "Receiver is too evil"; break;
- case 0x13: msg = "User temporarily unavailable"; break;
- case 0x14: msg = "No match"; break;
- case 0x15: msg = "List overflow"; break;
- case 0x16: msg = "Request ambiguous"; break;
- case 0x17: msg = "Server queue full"; break;
- case 0x18: msg = "Not while on AOL"; break;
- case 0x19: msg = "Query failed"; break;
- case 0x1A: msg = "Timeout"; break;
- case 0x1C: msg = "General failure"; break;
- case 0x1D: msg = "Progress"; break;
- case 0x1E: msg = "In free area"; break;
- case 0x1F: msg = "Restricted by parental controls"; break;
- case 0x20: msg = "Remote restricted by parental controls"; break;
- default: msg = ""; break;
- }
-
- debugLogA("SNAC(x%02X,x01) - Error(%u): %s", wFamily, wError, msg);
-}
diff --git a/protocols/IcqOscarJ/src/chan_03error.cpp b/protocols/IcqOscarJ/src/chan_03error.cpp
deleted file mode 100644
index 5e0487b5a5..0000000000
--- a/protocols/IcqOscarJ/src/chan_03error.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001,2002 Jon Keating, Richard Hughes
-// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004,2005 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleErrorChannel(unsigned char*, size_t)
-{
- debugLogA("Ignoring server packet on ERROR channel");
-}
diff --git a/protocols/IcqOscarJ/src/chan_04close.cpp b/protocols/IcqOscarJ/src/chan_04close.cpp
deleted file mode 100644
index 8f4883d0a9..0000000000
--- a/protocols/IcqOscarJ/src/chan_04close.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleCloseChannel(BYTE *buf, size_t datalen, serverthread_info *info)
-{
- oscar_tlv_chain *chain = nullptr;
-
- // Parse server reply, prepare reconnection
- if (!info->bLoggedIn && datalen && !info->isNewServerReady)
- handleLoginReply(buf, datalen, info);
-
- if (info->isMigrating)
- handleMigration(info);
-
- if ((!info->bLoggedIn || info->isMigrating) && info->isNewServerReady) {
- if (!connectNewServer(info)) { // Connecting failed
- if (info->isMigrating)
- icq_LogUsingErrorCode(LOG_ERROR, GetLastError(), LPGEN("Unable to connect to migrated ICQ communication server"));
- else
- icq_LogUsingErrorCode(LOG_ERROR, GetLastError(), LPGEN("Unable to connect to ICQ communication server"));
-
- SetCurrentStatus(ID_STATUS_OFFLINE);
-
- info->isMigrating = false;
- }
- info->isNewServerReady = false;
- return;
- }
-
- if (chain = readIntoTLVChain(&buf, datalen, 0)) {
- // TLV 9 errors (runtime errors?)
- WORD wError = chain->getWord(0x09, 1);
- if (wError) {
- SetCurrentStatus(ID_STATUS_OFFLINE);
-
- handleRuntimeError(wError);
- }
-
- disposeChain(&chain);
- }
- // Server closed connection on error, or sign off
- NetLib_CloseConnection(&hServerConn, TRUE);
-}
-
-void CIcqProto::handleLoginReply(BYTE *buf, size_t datalen, serverthread_info *info)
-{
- oscar_tlv_chain *chain = nullptr;
-
- icq_sendCloseConnection(); // imitate icq5 behaviour
-
- if (!(chain = readIntoTLVChain(&buf, datalen, 0))) {
- debugLogA("Error: Missing chain on close channel");
- NetLib_CloseConnection(&hServerConn, TRUE);
- return; // Invalid data
- }
-
- // TLV 8 errors (signon errors?)
- WORD wError = chain->getWord(0x08, 1);
- if (wError) {
- handleSignonError(wError);
-
- // we return only if the server did not gave us cookie (possible to connect with soft error)
- if (!chain->getLength(0x06, 1)) {
- disposeChain(&chain);
- icq_serverDisconnect();
- return; // Failure
- }
- }
-
- // We are in the login phase and no errors were reported.
- // Extract communication server info.
- info->newServer = chain->getString(0x05, 1);
- info->newServerSSL = chain->getNumber(0x8E, 1);
- info->cookieData = (BYTE*)chain->getString(0x06, 1);
- info->cookieDataLen = chain->getLength(0x06, 1);
-
- // We dont need this anymore
- disposeChain(&chain);
-
- if (!info->newServer || !info->cookieData) {
- icq_LogMessage(LOG_FATAL, LPGEN("You could not sign on because the server returned invalid data. Try again."));
-
- SAFE_FREE(&info->newServer);
- SAFE_FREE((void**)&info->cookieData);
- info->cookieDataLen = 0;
-
- SetCurrentStatus(ID_STATUS_OFFLINE);
- NetLib_CloseConnection(&hServerConn, TRUE);
- return; // Failure
- }
-
- debugLogA("Authenticated.");
- info->isNewServerReady = true;
-}
-
-int CIcqProto::connectNewServer(serverthread_info *info)
-{
- int res = 0;
-
- /* Get the ip and port */
- WORD wServerPort = info->wServerPort; // prepare default port
- parseServerAddress(info->newServer, &wServerPort);
-
- NETLIBOPENCONNECTION nloc = { 0 };
- nloc.flags = 0;
- nloc.szHost = info->newServer;
- nloc.wPort = wServerPort;
-
- if (!m_bGatewayMode) {
- NetLib_SafeCloseHandle(&info->hPacketRecver);
- NetLib_CloseConnection(&hServerConn, TRUE);
-
- debugLogA("Closed connection to login server");
-
- hServerConn = NetLib_OpenConnection(m_hNetlibUser, nullptr, &nloc);
- if (hServerConn && info->newServerSSL) /* Start SSL session if requested */
- if (!Netlib_StartSsl(hServerConn, nullptr))
- NetLib_CloseConnection(&hServerConn, FALSE);
-
- if (hServerConn) {
- /* Time to recreate the packet receiver */
- info->hPacketRecver = Netlib_CreatePacketReceiver(hServerConn, 0x2400);
- if (!info->hPacketRecver)
- debugLogA("Error: Failed to create packet receiver.");
- else { // we need to reset receiving structs
- info->bReinitRecver = true;
- res = 1;
- }
- }
- }
- else { // TODO: We should really do some checks here
- debugLogA("Walking in Gateway to %s", info->newServer);
- // TODO: This REQUIRES more work (most probably some kind of mid-netlib module)
- icq_httpGatewayWalkTo(hServerConn, &nloc);
- res = 1;
- }
- if (!res) SAFE_FREE((void**)&info->cookieData);
-
- // Free allocated memory
- // NOTE: "cookie" will get freed when we have connected to the communication server.
- SAFE_FREE(&info->newServer);
-
- return res;
-}
-
-void CIcqProto::handleMigration(serverthread_info *info)
-{
- // Check the data that was saved when the migration was announced
- debugLogA("Migrating to %s", info->newServer);
- if (!info->newServer || !info->cookieData) {
- icq_LogMessage(LOG_FATAL, LPGEN("You have been disconnected from the ICQ network because the current server shut down."));
-
- SAFE_FREE(&info->newServer);
- SAFE_FREE((void**)&info->cookieData);
- info->isNewServerReady = info->isMigrating = false;
- }
-}
-
-void CIcqProto::handleSignonError(WORD wError)
-{
- switch (wError) {
-
- case 0x01: // Unregistered uin
- case 0x04: // Incorrect uin or password
- case 0x05: // Mismatch uin or password
- case 0x06: // Internal Client error (bad input to authorizer)
- case 0x07: // Invalid account
- ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_WRONGPASSWORD);
- memset(m_szPassword, 0, sizeof(m_szPassword));
- icq_LogFatalParam(LPGEN("Connection failed.\nYour ICQ number or password was rejected (%d)."), wError);
- break;
-
- case 0x02: // Service temporarily unavailable
- case 0x0D: // Bad database status
- case 0x10: // Service temporarily offline
- case 0x12: // Database send error
- case 0x14: // Reservation map error
- case 0x15: // Reservation link error
- case 0x1A: // Reservation timeout
- ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_NOSERVER);
- icq_LogFatalParam(LPGEN("Connection failed.\nThe server is temporarily unavailable (%d)."), wError);
- break;
-
- case 0x16: // The users num connected from this IP has reached the maximum
- case 0x17: // The users num connected from this IP has reached the maximum (reserved)
- icq_LogFatalParam(LPGEN("Connection failed.\nServer has too many connections from your IP (%d)."), wError);
- break;
-
- case 0x18: // Reservation rate limit exceeded
- case 0x1D: // Rate limit exceeded
- ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_NOSERVER);
- icq_LogFatalParam(LPGEN("Connection failed.\nYou have connected too quickly,\nplease wait and retry 10 to 20 minutes later (%d)."), wError);
- break;
-
- case 0x1B: // You are using an older version of ICQ. Upgrade required
- ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_WRONGPROTOCOL);
- icq_LogMessage(LOG_FATAL, LPGEN("Connection failed.\nThe server did not accept this client version."));
- break;
-
- case 0x1C: // You are using an older version of ICQ. Upgrade recommended
- icq_LogMessage(LOG_WARNING, LPGEN("The server sent warning, this version is getting old.\nTry to look for a new one."));
- break;
-
- case 0x1E: // Can't register on the ICQ network
- icq_LogMessage(LOG_FATAL, LPGEN("Connection failed.\nYou were rejected by the server for an unknown reason.\nThis can happen if the UIN is already connected."));
- break;
-
- case 0x0C: // Invalid database fields, MD5 login not supported
- icq_LogMessage(LOG_FATAL, LPGEN("Connection failed.\nSecure (MD5) login is not supported on this account."));
- break;
-
- case 0: // No error
- break;
-
- case 0x08: // Deleted account
- case 0x09: // Expired account
- case 0x0A: // No access to database
- case 0x0B: // No access to resolver
- case 0x0E: // Bad resolver status
- case 0x0F: // Internal error
- case 0x11: // Suspended account
- case 0x13: // Database link error
- case 0x19: // User too heavily warned
- case 0x1F: // Token server timeout
- case 0x20: // Invalid SecureID number
- case 0x21: // MC error
- case 0x22: // Age restriction
- case 0x23: // RequireRevalidation
- case 0x24: // Link rule rejected
- case 0x25: // Missing information or bad SNAC format
- case 0x26: // Link broken
- case 0x27: // Invalid client IP
- case 0x28: // Partner rejected
- case 0x29: // SecureID missing
- case 0x2A: // Blocked account | Bump user
-
- default:
- icq_LogFatalParam(LPGEN("Connection failed.\nUnknown error during sign on: 0x%02x"), wError);
- break;
- }
-}
-
-void CIcqProto::handleRuntimeError(WORD wError)
-{
- switch (wError) {
- case 0x01:
- ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_OTHERLOCATION);
- icq_LogMessage(LOG_FATAL, LPGEN("You have been disconnected from the ICQ network because you logged on from another location using the same ICQ number."));
- break;
-
- default:
- icq_LogFatalParam(LPGEN("Unknown runtime error: 0x%02x"), wError);
- break;
- }
-}
diff --git a/protocols/IcqOscarJ/src/chan_05ping.cpp b/protocols/IcqOscarJ/src/chan_05ping.cpp
deleted file mode 100644
index 05cbc27d74..0000000000
--- a/protocols/IcqOscarJ/src/chan_05ping.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handlePingChannel(BYTE*, size_t)
-{
- debugLogA("Warning: Ignoring server packet on PING channel");
-}
-
-void CIcqProto::StartKeepAlive(serverthread_info *info)
-{
- if (getByte("KeepAlive", DEFAULT_KEEPALIVE_ENABLED))
- info->tmPing = time(0) + KEEPALIVE_INTERVAL;
- else
- info->tmPing = -1;
-}
-
-void CIcqProto::StopKeepAlive(serverthread_info *info)
-{
- info->tmPing = -1;
-}
-
-void CIcqProto::CheckKeepAlive(serverthread_info *info)
-{
- if (info->tmPing == -1)
- return;
-
- if (time(0) >= info->tmPing) {
- // Send a keep alive packet to server
- icq_packet packet = { 0 };
- write_flap(&packet, ICQ_PING_CHAN);
- sendServPacket(&packet);
-
- StartKeepAlive(info);
- }
-}
diff --git a/protocols/IcqOscarJ/src/changeinfo.h b/protocols/IcqOscarJ/src/changeinfo.h
deleted file mode 100644
index ef4de019a6..0000000000
--- a/protocols/IcqOscarJ/src/changeinfo.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2001-2004 Richard Hughes, Martin Öberg
-// Copyright © 2004-2010 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// ChangeInfo Plugin stuff
-// -----------------------------------------------------------------------------
-
-#ifndef __CHANGEINFO_H
-#define __CHANGEINFO_H
-
-
-#ifndef AW_SLIDE
-#define SPI_GETCOMBOBOXANIMATION 0x1004
-#define AW_SLIDE 0x40000
-#define AW_ACTIVATE 0x20000
-#define AW_VER_POSITIVE 0x4
-#define UDM_SETPOS32 (WM_USER+113)
-#define UDM_GETPOS32 (WM_USER+114)
-#endif
-
-
-#define LI_DIVIDER 0
-#define LI_STRING 1
-#define LI_LIST 2
-#define LI_LONGSTRING 3
-#define LI_NUMBER 4
-#define LIM_TYPE 0x0000FFFF
-#define LIF_ZEROISVALID 0x80000000
-#define LIF_SIGNED 0x40000000
-#define LIF_PASSWORD 0x20000000
-#define LIF_CHANGEONLY 0x10000000
-
-struct SettingItem
-{
- const char *szDescription;
- unsigned displayType; //LI_ constant
- int dbType; //DBVT_ constant
- const char *szDbSetting;
- const void *pList;
-};
-
-struct SettingItemData
-{
- LPARAM value;
- int changed;
-};
-
-// contants.c
-extern const SettingItem setting[];
-extern const int settingCount;
-
-//dlgproc.c
-struct ChangeInfoData : public MZeroedObject
-{
- HWND hwndDlg;
- CIcqProto *ppro;
- HFONT hListFont;
- HWND hwndList;
- int editTopIndex;
- int iEditItem;
- char Password[PASSWORDMAXLEN + 1];
-
- SettingItemData *settingData;
-
- HANDLE hAckHook;
- HANDLE hUpload[2];
-
- ChangeInfoData() { settingData = (SettingItemData*)SAFE_MALLOC(sizeof(SettingItemData) * settingCount); hAckHook = nullptr; hUpload[0] = nullptr; hUpload[1] = nullptr; }
- ~ChangeInfoData() { SAFE_FREE((void**)&settingData); }
-
- char* GetItemSettingText(int i, char *buf, size_t buf_size);
- void PaintItemSetting(HDC hdc, RECT *rc, int i, UINT itemState);
-
- //db.cpp
- void LoadSettingsFromDb(int keepChanged);
- void FreeStoredDbSettings(void);
- int ChangesMade(void);
- void ClearChangeFlags(void);
- int SaveSettingsToDb(void);
-
- //upload.cpp
- int UploadSettings(void);
-
- //editstring.cpp
- void BeginStringEdit(int iItem, RECT *rc, int i, WORD wVKey);
- void EndStringEdit(int save);
- //editlist.cpp
- void BeginListEdit(int iItem, RECT *rc, int iSetting, WORD wVKey);
- void EndListEdit(int save);
-};
-
-INT_PTR CALLBACK ChangeInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-
-//editstring.c
-int IsStringEditWindow(HWND hwnd);
-char* BinaryToEscapes(char *str);
-
-//editlist.c
-int IsListEditWindow(HWND hwnd);
-
-#endif /* __CHANGEINFO_H */
diff --git a/protocols/IcqOscarJ/src/channels.h b/protocols/IcqOscarJ/src/channels.h
deleted file mode 100644
index 6bce28b5b8..0000000000
--- a/protocols/IcqOscarJ/src/channels.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Header for FLAP Channel packet handlers
-// -----------------------------------------------------------------------------
-
-#ifndef __CHANNELS_H
-#define __CHANNELS_H
-
-struct snac_header
-{
- BOOL bValid;
- WORD wFamily;
- WORD wSubtype;
- WORD wFlags;
- DWORD dwRef;
- WORD wVersion;
-};
-
-int unpackSnacHeader(snac_header *pSnacHeader, BYTE **pBuffer, size_t *pwBufferLength);
-
-#endif /* __CHANNELS_H */
diff --git a/protocols/IcqOscarJ/src/constants.cpp b/protocols/IcqOscarJ/src/constants.cpp
deleted file mode 100644
index d07e8352f5..0000000000
--- a/protocols/IcqOscarJ/src/constants.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2001-2004 Richard Hughes, Martin Öberg
-// Copyright © 2004-2009 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// ChangeInfo Plugin stuff
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-static FieldNamesItem months[] = {
- { 1, LPGEN("January") },
- { 2, LPGEN("February") },
- { 3, LPGEN("March") },
- { 4, LPGEN("April") },
- { 5, LPGEN("May") },
- { 6, LPGEN("June") },
- { 7, LPGEN("July") },
- { 8, LPGEN("August") },
- { 9, LPGEN("September") },
- { 10, LPGEN("October") },
- { 11, LPGEN("November") },
- { 12, LPGEN("December") },
- { 0, nullptr }
-};
-
-const int ageRange[] = { 13, 0x7FFF }; // 14, 130
-const int yearRange[] = { 1753, 0x7FFF }; // 1880, 2000
-const int dayRange[] = { 1, 31 };
-
-const SettingItem setting[] =
-{
- // personal
- { LPGEN("Personal"), LI_DIVIDER },
- { LPGEN("Nickname"), LI_STRING, DBVT_UTF8, "Nick" },
- { LPGEN("First name"), LI_STRING, DBVT_UTF8, "FirstName" },
- { LPGEN("Last name"), LI_STRING, DBVT_UTF8, "LastName" },
- { LPGEN("Gender"), LI_LIST, DBVT_BYTE, "Gender", genderField },
- { LPGEN("About"), LI_LONGSTRING, DBVT_UTF8, "About" },
-
- // password
- { LPGEN("Password"), LI_DIVIDER },
- { LPGEN("Password"), LI_STRING | LIF_PASSWORD, DBVT_UTF8, "Password" },
-
- // contact
- { LPGEN("Contact"), LI_DIVIDER },
- { LPGEN("Primary e-mail"), LI_STRING, DBVT_UTF8, "e-mail0" },
- { LPGEN("Secondary e-mail"), LI_STRING, DBVT_UTF8, "e-mail1" },
- { LPGEN("Tertiary e-mail"), LI_STRING, DBVT_UTF8, "e-mail2" },
- { LPGEN("Homepage"), LI_STRING, DBVT_UTF8, "Homepage" },
- { LPGEN("Street"), LI_STRING, DBVT_UTF8, "Street" },
- { LPGEN("City"), LI_STRING, DBVT_UTF8, "City" },
- { LPGEN("State"), LI_STRING, DBVT_UTF8, "State" },
- { LPGEN("ZIP/postcode"), LI_STRING, DBVT_UTF8, "ZIP" },
- { LPGEN("Country"), LI_LIST, DBVT_WORD, "Country", countryField },
- { LPGEN("Phone number"), LI_STRING, DBVT_UTF8, "Phone" },
- { LPGEN("Fax number"), LI_STRING, DBVT_UTF8, "Fax" },
- { LPGEN("Cellular number"), LI_STRING, DBVT_UTF8, "Cellular" },
-
- // more
- { LPGEN("Personal Detail"), LI_DIVIDER },
- { LPGEN("Timezone"), LI_LIST | LIF_ZEROISVALID | LIF_SIGNED, DBVT_BYTE, "Timezone", timezonesField },
- { LPGEN("Year of birth"), LI_NUMBER, DBVT_WORD, "BirthYear", yearRange },
- { LPGEN("Month of birth"), LI_LIST, DBVT_BYTE, "BirthMonth", months },
- { LPGEN("Day of birth"), LI_NUMBER, DBVT_BYTE, "BirthDay", dayRange },
- { LPGEN("Marital Status"), LI_LIST, DBVT_BYTE, "MaritalStatus", maritalField },
- { LPGEN("Spoken language 1"), LI_LIST, DBVT_BYTE, "Language1", languageField },
- { LPGEN("Spoken language 2"), LI_LIST, DBVT_BYTE, "Language2", languageField },
- { LPGEN("Spoken language 3"), LI_LIST, DBVT_BYTE, "Language3", languageField },
-
- // more
- { LPGEN("Originally from"), LI_DIVIDER },
- { LPGEN("Street"), LI_STRING, DBVT_UTF8, "OriginStreet" },
- { LPGEN("City"), LI_STRING, DBVT_UTF8, "OriginCity" },
- { LPGEN("State"), LI_STRING, DBVT_UTF8, "OriginState" },
- { LPGEN("Country"), LI_LIST, DBVT_WORD, "OriginCountry", countryField },
-
- // study
- { LPGEN("Education"), LI_DIVIDER },
- { LPGEN("Level"), LI_LIST, DBVT_WORD, "StudyLevel", studyLevelField },
- { LPGEN("Institute"), LI_STRING, DBVT_UTF8, "StudyInstitute" },
- { LPGEN("Degree"), LI_STRING, DBVT_UTF8, "StudyDegree" },
- { LPGEN("Graduation Year"), LI_NUMBER, DBVT_WORD, "StudyYear", yearRange },
-
- // work
- { LPGEN("Work"), LI_DIVIDER },
- { LPGEN("Company name"), LI_STRING, DBVT_UTF8, "Company" },
- { LPGEN("Company homepage"), LI_STRING, DBVT_UTF8, "CompanyHomepage" },
- { LPGEN("Company street"), LI_STRING, DBVT_UTF8, "CompanyStreet" },
- { LPGEN("Company city"), LI_STRING, DBVT_UTF8, "CompanyCity" },
- { LPGEN("Company state"), LI_STRING, DBVT_UTF8, "CompanyState" },
- { LPGEN("Company phone"), LI_STRING, DBVT_UTF8, "CompanyPhone" },
- { LPGEN("Company fax"), LI_STRING, DBVT_UTF8, "CompanyFax" },
- { LPGEN("Company ZIP/postcode"), LI_STRING, DBVT_UTF8, "CompanyZIP" },
- { LPGEN("Company country"), LI_LIST, DBVT_WORD, "CompanyCountry", countryField },
- { LPGEN("Company department"), LI_STRING, DBVT_UTF8, "CompanyDepartment" },
- { LPGEN("Company position"), LI_STRING, DBVT_UTF8, "CompanyPosition" },
- { LPGEN("Company industry"), LI_LIST, DBVT_WORD, "CompanyIndustry", industryField },
-
- //interests
- { LPGEN("Personal Interests"), LI_DIVIDER },
- { LPGEN("Interest category 1"), LI_LIST, DBVT_WORD, "Interest0Cat", interestsField },
- { LPGEN("Interest areas 1"), LI_STRING, DBVT_UTF8, "Interest0Text" },
- { LPGEN("Interest category 2"), LI_LIST, DBVT_WORD, "Interest1Cat", interestsField },
- { LPGEN("Interest areas 2"), LI_STRING, DBVT_UTF8, "Interest1Text" },
- { LPGEN("Interest category 3"), LI_LIST, DBVT_WORD, "Interest2Cat", interestsField },
- { LPGEN("Interest areas 3"), LI_STRING, DBVT_UTF8, "Interest2Text" },
- { LPGEN("Interest category 4"), LI_LIST, DBVT_WORD, "Interest3Cat", interestsField },
- { LPGEN("Interest areas 4"), LI_STRING, DBVT_UTF8, "Interest3Text" },
-};
-
-const int settingCount = _countof(setting);
diff --git a/protocols/IcqOscarJ/src/cookies.cpp b/protocols/IcqOscarJ/src/cookies.cpp
deleted file mode 100644
index a9d09534c7..0000000000
--- a/protocols/IcqOscarJ/src/cookies.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Handles packet & message cookies
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::RemoveExpiredCookies()
-{
- time_t tNow = time(0);
-
- auto T = cookies.rev_iter();
- for (auto &it : T)
- if (it->dwTime + COOKIE_TIMEOUT < tNow)
- cookies.remove(T.indexOf(&it));
-}
-
-// Generate and allocate cookie
-DWORD CIcqProto::AllocateCookie(BYTE bType, WORD wIdent, MCONTACT hContact, void *pvExtra)
-{
- mir_cslock l(cookieMutex);
-
- DWORD dwThisSeq = wCookieSeq++;
- dwThisSeq &= 0x7FFF;
- dwThisSeq |= wIdent << 0x10;
-
- icq_cookie_info *p = new icq_cookie_info();
- p->bType = bType;
- p->dwCookie = dwThisSeq;
- p->hContact = hContact;
- p->pvExtra = pvExtra;
- p->dwTime = time(0);
- cookies.insert(p);
-
- return dwThisSeq;
-}
-
-DWORD CIcqProto::GenerateCookie(WORD wIdent)
-{
- mir_cslock l(cookieMutex);
-
- DWORD dwThisSeq = wCookieSeq++;
- dwThisSeq &= 0x7FFF;
- dwThisSeq |= wIdent << 0x10;
- return dwThisSeq;
-}
-
-int CIcqProto::GetCookieType(DWORD dwCookie)
-{
- mir_cslock l(cookieMutex);
-
- int i = cookies.getIndex((icq_cookie_info*)&dwCookie);
- if (i != -1)
- i = cookies[i].bType;
-
- return i;
-}
-
-int CIcqProto::FindCookie(DWORD dwCookie, MCONTACT *phContact, void **ppvExtra)
-{
- mir_cslock l(cookieMutex);
-
- int i = cookies.getIndex((icq_cookie_info*)&dwCookie);
- if (i != -1) {
- if (phContact)
- *phContact = cookies[i].hContact;
- if (ppvExtra)
- *ppvExtra = cookies[i].pvExtra;
-
- // Cookie found
- return 1;
- }
-
- return 0;
-}
-
-int CIcqProto::FindCookieByData(void *pvExtra, DWORD *pdwCookie, MCONTACT *phContact)
-{
- mir_cslock l(cookieMutex);
-
- for (auto &it : cookies) {
- if (pvExtra == it->pvExtra) {
- if (phContact)
- *phContact = it->hContact;
- if (pdwCookie)
- *pdwCookie = it->dwCookie;
-
- // Cookie found
- return 1;
- }
- }
-
- return 0;
-}
-
-int CIcqProto::FindCookieByType(BYTE bType, DWORD *pdwCookie, MCONTACT *phContact, void **ppvExtra)
-{
- mir_cslock l(cookieMutex);
-
- for (auto &it : cookies) {
- if (bType == it->bType) {
- if (pdwCookie)
- *pdwCookie = it->dwCookie;
- if (phContact)
- *phContact = it->hContact;
- if (ppvExtra)
- *ppvExtra = it->pvExtra;
-
- // Cookie found
- return 1;
- }
- }
-
- return 0;
-}
-
-int CIcqProto::FindMessageCookie(DWORD dwMsgID1, DWORD dwMsgID2, DWORD *pdwCookie, MCONTACT *phContact, cookie_message_data **ppvExtra)
-{
- mir_cslock l(cookieMutex);
-
- for (auto &it : cookies) {
- if (it->bType == CKT_MESSAGE || it->bType == CKT_FILE || it->bType == CKT_REVERSEDIRECT) {
- // message cookie found
- cookie_message_data *pCookie = (cookie_message_data*)it->pvExtra;
-
- if (pCookie->dwMsgID1 == dwMsgID1 && pCookie->dwMsgID2 == dwMsgID2) {
- if (phContact)
- *phContact = it->hContact;
- if (pdwCookie)
- *pdwCookie = it->dwCookie;
- if (ppvExtra)
- *ppvExtra = pCookie;
-
- // Cookie found
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-void CIcqProto::FreeCookie(DWORD dwCookie)
-{
- mir_cslock l(cookieMutex);
-
- int i = cookies.getIndex((icq_cookie_info*)&dwCookie);
- if (i != -1) // Cookie found, remove from list
- cookies.remove(i);
-
- RemoveExpiredCookies();
-}
-
-void CIcqProto::FreeCookieByData(BYTE bType, void *pvExtra)
-{
- mir_cslock l(cookieMutex);
-
- for (auto &it : cookies) {
- if (bType == it->bType && pvExtra == it->pvExtra) {
- // Cookie found, remove from list
- cookies.removeItem(&it);
- break;
- }
- }
-
- RemoveExpiredCookies();
-}
-
-void CIcqProto::ReleaseCookie(DWORD dwCookie)
-{
- mir_cslock l(cookieMutex);
-
- int i = cookies.getIndex((icq_cookie_info*)&dwCookie);
- if (i != -1) { // Cookie found, remove from list
- SAFE_FREE((void**)&cookies[i].pvExtra);
- cookies.remove(i);
- }
-
- RemoveExpiredCookies();
-}
-
-void CIcqProto::InitMessageCookie(cookie_message_data *pCookie)
-{
- DWORD dwMsgID1;
- DWORD dwMsgID2;
-
- do {
- // ensure that message ids are unique
- dwMsgID1 = time(0);
- dwMsgID2 = RandRange(0, 0x0FFFF);
- } while (FindMessageCookie(dwMsgID1, dwMsgID2, nullptr, nullptr, nullptr));
-
- if (pCookie) {
- pCookie->dwMsgID1 = dwMsgID1;
- pCookie->dwMsgID2 = dwMsgID2;
- }
-}
-
-cookie_message_data* CIcqProto::CreateMessageCookie(WORD bMsgType, BYTE bAckType)
-{
- cookie_message_data *pCookie = (cookie_message_data*)SAFE_MALLOC(sizeof(cookie_message_data));
- if (pCookie) {
- pCookie->bMessageType = bMsgType;
- pCookie->nAckType = bAckType;
-
- InitMessageCookie(pCookie);
- }
- return pCookie;
-}
-
-cookie_message_data* CIcqProto::CreateMessageCookieData(BYTE bMsgType, MCONTACT hContact, DWORD dwUin, int bUseSrvRelay)
-{
- BYTE bAckType;
- WORD wStatus = getContactStatus(hContact);
-
- if (!getByte(hContact, "SlowSend", getByte("SlowSend", DEFAULT_SLOWSEND)) || (!dwUin && wStatus == ID_STATUS_OFFLINE))
- bAckType = ACKTYPE_NONE;
- else if (bUseSrvRelay)
- bAckType = ACKTYPE_CLIENT;
- else
- bAckType = ACKTYPE_SERVER;
-
- cookie_message_data* pCookieData = CreateMessageCookie(bMsgType, bAckType);
-
- // set flag for offline messages - to allow proper error handling
- if (wStatus == ID_STATUS_OFFLINE || wStatus == ID_STATUS_INVISIBLE)
- pCookieData->isOffline = TRUE;
-
- return pCookieData;
-}
diff --git a/protocols/IcqOscarJ/src/cookies.h b/protocols/IcqOscarJ/src/cookies.h
deleted file mode 100644
index ad8c1bb306..0000000000
--- a/protocols/IcqOscarJ/src/cookies.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#ifndef __COOKIES_H
-#define __COOKIES_H
-
-#define CKT_MESSAGE 0x01
-#define CKT_FILE 0x02
-#define CKT_SEARCH 0x04
-#define CKT_SERVERLIST 0x08
-#define CKT_SERVICEREQUEST 0x0A
-#define CKT_REVERSEDIRECT 0x0C
-#define CKT_FAMILYSPECIAL 0x10
-#define CKT_OFFLINEMESSAGE 0x12
-#define CKT_DIRECTORY_QUERY 0x18
-#define CKT_DIRECTORY_UPDATE 0x19
-#define CKT_AVATAR 0x20
-
-struct CIcqProto;
-
-/* Basic structure used to hold operation cookies list */
-
-struct icq_cookie_info : public MZeroedObject
-{
- DWORD dwCookie;
- MCONTACT hContact;
- void *pvExtra;
- time_t dwTime;
- BYTE bType;
-};
-
-/* Specific structures to hold request specific data - pvExtra */
-
-struct cookie_family_request
-{
- WORD wFamily;
- void (CIcqProto::*familyHandler)(HNETLIBCONN hConn, char* cookie, size_t cookieLen);
-};
-
-struct cookie_offline_messages
-{
- int nMessages;
- int nMissed;
-};
-
-#define ACKTYPE_NONE 0
-#define ACKTYPE_SERVER 1
-#define ACKTYPE_CLIENT 2
-
-struct cookie_message_data
-{
- DWORD dwMsgID1;
- DWORD dwMsgID2;
- WORD bMessageType;
- BYTE nAckType;
- BYTE isOffline;
-};
-
-#define REQUESTTYPE_OWNER 0
-#define REQUESTTYPE_USERAUTO 1
-#define REQUESTTYPE_USERMINIMAL 2
-#define REQUESTTYPE_USERDETAILED 3
-#define REQUESTTYPE_PROFILE 4
-
-struct cookie_fam15_data
-{
- BYTE bRequestType;
-};
-
-#define SEARCHTYPE_UID 0
-#define SEARCHTYPE_EMAIL 1
-#define SEARCHTYPE_NAMES 2
-#define SEARCHTYPE_DETAILS 4
-
-struct cookie_search
-{
- BYTE bSearchType;
- char* szObject;
- DWORD dwMainId;
- DWORD dwStatus;
-};
-
-struct cookie_avatar
-{
- DWORD dwUin;
- MCONTACT hContact;
- size_t hashlen;
- BYTE *hash;
- size_t cbData;
- wchar_t *szFile;
-};
-
-struct cookie_reverse_connect : public cookie_message_data
-{
- MCONTACT hContact;
- DWORD dwUin;
- int type;
- void *ft;
-};
-
-#define DIRECTORYREQUEST_INFOUSER 0x01
-#define DIRECTORYREQUEST_INFOOWNER 0x02
-#define DIRECTORYREQUEST_INFOMULTI 0x03
-#define DIRECTORYREQUEST_SEARCH 0x08
-#define DIRECTORYREQUEST_UPDATEOWNER 0x10
-#define DIRECTORYREQUEST_UPDATENOTE 0x11
-#define DIRECTORYREQUEST_UPDATEPRIVACY 0x12
-
-struct cookie_directory_data
-{
- BYTE bRequestType;
-};
-
-#endif /* __COOKIES_H */
diff --git a/protocols/IcqOscarJ/src/db.cpp b/protocols/IcqOscarJ/src/db.cpp
deleted file mode 100644
index f07b2b0594..0000000000
--- a/protocols/IcqOscarJ/src/db.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2001-2004 Richard Hughes, Martin Öberg
-// Copyright © 2004-2009 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// ChangeInfo Plugin stuff
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void ChangeInfoData::LoadSettingsFromDb(int keepChanged)
-{
- for (int i = 0; i < settingCount; i++) {
- const SettingItem &si = setting[i];
- if (si.displayType == LI_DIVIDER)
- continue;
-
- SettingItemData &sid = settingData[i];
- if (keepChanged && sid.changed)
- continue;
-
- if (si.dbType == DBVT_ASCIIZ || si.dbType == DBVT_UTF8)
- SAFE_FREE((void**)(char**)&sid.value);
- else if (!keepChanged)
- sid.value = 0;
-
- sid.changed = 0;
-
- if (si.displayType & LIF_PASSWORD)
- continue;
-
- DBVARIANT dbv = { DBVT_DELETED };
- if (!ppro->getSetting(NULL, si.szDbSetting, &dbv)) {
- switch (dbv.type) {
- case DBVT_ASCIIZ:
- sid.value = (LPARAM)ppro->getSettingStringUtf(NULL, si.szDbSetting, nullptr);
- break;
-
- case DBVT_UTF8:
- sid.value = (LPARAM)null_strdup(dbv.pszVal);
- break;
-
- case DBVT_WORD:
- if (si.displayType & LIF_SIGNED)
- sid.value = dbv.sVal;
- else
- sid.value = dbv.wVal;
- break;
-
- case DBVT_BYTE:
- if (si.displayType & LIF_SIGNED)
- sid.value = dbv.cVal;
- else
- sid.value = dbv.bVal;
- break;
-
-#ifdef _DEBUG
- default:
- MessageBoxA(nullptr, "That's not supposed to happen either", "Huh?", MB_OK);
- break;
-#endif
- }
- db_free(&dbv);
- }
-
- char buf[MAX_PATH];
- wchar_t tbuf[MAX_PATH];
-
- if (make_unicode_string_static(GetItemSettingText(i, buf, _countof(buf)), tbuf, _countof(tbuf)))
- ListView_SetItemText(hwndList, i, 1, tbuf);
- }
-}
-
-void ChangeInfoData::FreeStoredDbSettings(void)
-{
- for (int i = 0; i < settingCount; i++)
- if (setting[i].dbType == DBVT_ASCIIZ || setting[i].dbType == DBVT_UTF8)
- SAFE_FREE((void**)&settingData[i].value);
-}
-
-int ChangeInfoData::ChangesMade(void)
-{
- for (int i = 0; i < settingCount; i++)
- if (settingData[i].changed)
- return 1;
- return 0;
-}
-
-void ChangeInfoData::ClearChangeFlags(void)
-{
- for (int i = 0; i < settingCount; i++)
- settingData[i].changed = 0;
-}
-
-int ChangeInfoData::SaveSettingsToDb()
-{
- int ret = 1;
-
- for (int i = 0; i < settingCount; i++) {
- SettingItemData &sid = settingData[i];
- if (!sid.changed)
- continue;
-
- const SettingItem &si = setting[i];
- if (!(si.displayType & LIF_ZEROISVALID) && sid.value == 0) {
- ppro->delSetting(si.szDbSetting);
- continue;
- }
- switch (si.dbType) {
- case DBVT_ASCIIZ:
- if (*(char*)sid.value)
- db_set_utf(NULL, ppro->m_szModuleName, si.szDbSetting, (char*)sid.value);
- else
- ppro->delSetting(si.szDbSetting);
- break;
-
- case DBVT_UTF8:
- if (*(char*)sid.value)
- db_set_utf(NULL, ppro->m_szModuleName, si.szDbSetting, (char*)sid.value);
- else
- ppro->delSetting(si.szDbSetting);
- break;
-
- case DBVT_WORD:
- ppro->setWord(si.szDbSetting, (WORD)sid.value);
- break;
-
- case DBVT_BYTE:
- ppro->setByte(si.szDbSetting, (BYTE)sid.value);
- break;
- }
- }
- return ret;
-}
diff --git a/protocols/IcqOscarJ/src/directpackets.cpp b/protocols/IcqOscarJ/src/directpackets.cpp
deleted file mode 100644
index a7f32e7248..0000000000
--- a/protocols/IcqOscarJ/src/directpackets.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void EncryptDirectPacket(directconnect* dc, icq_packet* p);
-
-void packEmptyMsg(icq_packet *packet);
-
-static void packDirectMsgHeader(icq_packet* packet, size_t wDataLen, WORD wCommand, DWORD dwCookie, BYTE bMsgType, BYTE bMsgFlags, WORD wX1, WORD wX2)
-{
- directPacketInit(packet, 29 + wDataLen);
- packByte(packet, 2); /* channel */
- packLEDWord(packet, 0); /* space for crypto */
- packLEWord(packet, wCommand);
- packLEWord(packet, 14); /* unknown */
- packLEWord(packet, (WORD)dwCookie);
- packLEDWord(packet, 0); /* unknown */
- packLEDWord(packet, 0); /* unknown */
- packLEDWord(packet, 0); /* unknown */
- packByte(packet, bMsgType);
- packByte(packet, bMsgFlags);
- packLEWord(packet, wX1); /* unknown. Is 1 for getawaymsg, 0 otherwise */
- packLEWord(packet, wX2); // this is probably priority
-}
-
-
-void CIcqProto::icq_sendDirectMsgAck(directconnect* dc, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, char* szCap)
-{
- icq_packet packet;
- packDirectMsgHeader(&packet, bMsgType == MTYPE_PLAIN ? (szCap ? 53 : 11) : 3, DIRECT_ACK, wCookie, bMsgType, bMsgFlags, 0, 0);
- packEmptyMsg(&packet); /* empty message */
-
- if (bMsgType == MTYPE_PLAIN) {
- packMsgColorInfo(&packet);
-
- if (szCap) {
- packLEDWord(&packet, 0x26); /* CLSID length */
- packBuffer(&packet, (LPBYTE)szCap, 0x26); /* GUID */
- }
- }
- EncryptDirectPacket(dc, &packet);
- sendDirectPacket(dc, &packet);
-
- NetLog_Direct("Sent acknowledgement thru direct connection");
-}
-
-
-DWORD CIcqProto::icq_sendGetAwayMsgDirect(MCONTACT hContact, int type)
-{
- if (getWord(hContact, "Version", 0) >= 9)
- return 0; // v9 DC protocol does not support this message
-
- cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_AUTOAWAY, (BYTE)type);
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
-
- icq_packet packet;
- packDirectMsgHeader(&packet, 3, DIRECT_MESSAGE, dwCookie, (BYTE)type, 3, 1, 0);
- packEmptyMsg(&packet); // message
-
- return (SendDirectMessage(hContact, &packet)) ? dwCookie : 0;
-}
-
-
-void CIcqProto::icq_sendAwayMsgReplyDirect(directconnect* dc, WORD wCookie, BYTE msgType, const char** szMsg)
-{
- if (validateStatusMessageRequest(dc->hContact, msgType)) {
- NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dc->dwRemoteUin);
-
- mir_cslock l(m_modeMsgsMutex);
-
- if (szMsg && *szMsg) {
- // prepare Ansi message - only Ansi supported
- size_t wMsgLen = mir_strlen(*szMsg) + 1;
- char *szAnsiMsg = (char*)_alloca(wMsgLen);
-
- utf8_decode_static(*szMsg, szAnsiMsg, wMsgLen);
- wMsgLen = mir_strlen(szAnsiMsg);
-
- icq_packet packet;
- packDirectMsgHeader(&packet, 3 + wMsgLen, DIRECT_ACK, wCookie, msgType, 3, 0, 0);
- packLEWord(&packet, WORD(wMsgLen + 1));
- packBuffer(&packet, (LPBYTE)szAnsiMsg, wMsgLen + 1);
- EncryptDirectPacket(dc, &packet);
-
- sendDirectPacket(dc, &packet);
- }
- }
-}
-
-
-void CIcqProto::icq_sendFileAcceptDirect(MCONTACT hContact, filetransfer* ft)
-{
- // v7 packet
- icq_packet packet;
- packDirectMsgHeader(&packet, 18, DIRECT_ACK, ft->dwCookie, MTYPE_FILEREQ, 0, 0, 0);
- packLEWord(&packet, 1); // description
- packByte(&packet, 0);
- packWord(&packet, wListenPort);
- packLEWord(&packet, 0);
- packLEWord(&packet, 1); // filename
- packByte(&packet, 0); // TODO: really send filename
- packLEDWord(&packet, ft->dwTotalSize); // file size
- packLEDWord(&packet, wListenPort); // FIXME: ideally we want to open a new port for this
-
- SendDirectMessage(hContact, &packet);
-
- NetLog_Direct("Sent file accept direct, port %u", wListenPort);
-}
-
-
-void CIcqProto::icq_sendFileDenyDirect(MCONTACT hContact, filetransfer *ft, const char *szReason)
-{
- // v7 packet
- icq_packet packet;
- char *szReasonAnsi = nullptr;
- if (!utf8_decode(szReason, &szReasonAnsi))
- szReasonAnsi = _strdup(szReason); // Legacy fix
- size_t cbReasonAnsi = mir_strlen(szReasonAnsi);
-
- packDirectMsgHeader(&packet, 18 + cbReasonAnsi, DIRECT_ACK, ft->dwCookie, MTYPE_FILEREQ, 0, 1, 0);
- packLEWord(&packet, WORD(1 + cbReasonAnsi)); // description
- if (szReasonAnsi)
- packBuffer(&packet, (LPBYTE)szReasonAnsi, cbReasonAnsi);
- packByte(&packet, 0);
- packWord(&packet, 0);
- packLEWord(&packet, 0);
- packLEWord(&packet, 1); // filename
- packByte(&packet, 0); // TODO: really send filename
- packLEDWord(&packet, 0); // file size
- packLEDWord(&packet, 0);
-
- SAFE_FREE(&szReasonAnsi);
-
- SendDirectMessage(hContact, &packet);
-
- NetLog_Direct("Sent file deny direct.");
-}
-
-
-int CIcqProto::icq_sendFileSendDirectv7(filetransfer *ft, const char *pszFiles)
-{
- char *szFilesAnsi = nullptr;
- size_t wDescrLen = mir_strlen(ft->szDescription);
-
- if (!utf8_decode(pszFiles, &szFilesAnsi))
- szFilesAnsi = _strdup(pszFiles); // Legacy fix
- size_t wFilesLen = mir_strlen(szFilesAnsi);
-
- icq_packet packet;
- packDirectMsgHeader(&packet, 18 + wDescrLen + wFilesLen, DIRECT_MESSAGE, (WORD)ft->dwCookie, MTYPE_FILEREQ, 0, 0, 0);
- packLEWord(&packet, WORD(wDescrLen + 1));
- packBuffer(&packet, (LPBYTE)ft->szDescription, wDescrLen + 1);
- packLEDWord(&packet, 0); // listen port
- packLEWord(&packet, WORD(wFilesLen + 1));
- packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1);
- packLEDWord(&packet, ft->dwTotalSize);
- packLEDWord(&packet, 0); // listen port (again)
-
- SAFE_FREE(&szFilesAnsi);
-
- NetLog_Direct("Sending v%u file transfer request direct", 7);
-
- return SendDirectMessage(ft->hContact, &packet);
-}
-
-
-int CIcqProto::icq_sendFileSendDirectv8(filetransfer *ft, const char *pszFiles)
-{
- char *szFilesAnsi = nullptr;
- size_t wDescrLen = mir_strlen(ft->szDescription);
-
- if (!utf8_decode(pszFiles, &szFilesAnsi))
- szFilesAnsi = _strdup(pszFiles); // Legacy fix
- size_t wFilesLen = mir_strlen(szFilesAnsi) + 1;
-
- icq_packet packet;
- packDirectMsgHeader(&packet, 0x2E + 22 + wDescrLen + wFilesLen, DIRECT_MESSAGE, (WORD)ft->dwCookie, MTYPE_PLUGIN, 0, 0, 0);
- packEmptyMsg(&packet); // message
- packPluginTypeId(&packet, MTYPE_FILEREQ);
-
- packLEDWord(&packet, WORD(18 + wDescrLen + wFilesLen)); // Remaining length
- packLEDWord(&packet, DWORD(wDescrLen)); // Description
- packBuffer(&packet, (LPBYTE)ft->szDescription, wDescrLen);
- packWord(&packet, 0x8c82); // Unknown (port?), seen 0x80F6
- packWord(&packet, 0x0222); // Unknown, seen 0x2e01
- packLEWord(&packet, WORD(wFilesLen));
- packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen);
- packLEDWord(&packet, ft->dwTotalSize);
- packLEDWord(&packet, 0x0008c82); // Unknown, (seen 0xf680 ~33000)
-
- SAFE_FREE(&szFilesAnsi);
-
- NetLog_Direct("Sending v%u file transfer request direct", 8);
-
- return SendDirectMessage(ft->hContact, &packet);
-}
-
-
-DWORD CIcqProto::icq_SendDirectMessage(MCONTACT hContact, const char *szMessage, size_t nBodyLength, cookie_message_data *pCookieData, char *szCap)
-{
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
-
- // Pack the standard header
- icq_packet packet;
- packDirectMsgHeader(&packet, nBodyLength + (szCap ? 53 : 11), DIRECT_MESSAGE, dwCookie, (BYTE)pCookieData->bMessageType, 0, 0, 0);
-
- packLEWord(&packet, WORD(nBodyLength + 1)); // Length of message
- packBuffer(&packet, (LPBYTE)szMessage, nBodyLength + 1); // Message
- packMsgColorInfo(&packet);
- if (szCap) {
- packLEDWord(&packet, 0x00000026); // length of GUID
- packBuffer(&packet, (LPBYTE)szCap, 0x26); // UTF-8 GUID
- }
-
- if (SendDirectMessage(hContact, &packet))
- return dwCookie; // Success
-
- FreeCookie(dwCookie); // release cookie
- return 0; // Failure
-}
-
-void CIcqProto::icq_sendXtrazRequestDirect(MCONTACT hContact, DWORD dwCookie, char* szBody, size_t nBodyLen, WORD wType)
-{
- icq_packet packet;
- packDirectMsgHeader(&packet, 11 + getPluginTypeIdLen(wType) + nBodyLen, DIRECT_MESSAGE, dwCookie, MTYPE_PLUGIN, 0, 0, 1);
- packEmptyMsg(&packet); // message (unused)
- packPluginTypeId(&packet, wType);
-
- packLEDWord(&packet, DWORD(nBodyLen + 4));
- packLEDWord(&packet, DWORD(nBodyLen));
- packBuffer(&packet, (LPBYTE)szBody, nBodyLen);
-
- SendDirectMessage(hContact, &packet);
-}
-
-void CIcqProto::icq_sendXtrazResponseDirect(MCONTACT hContact, WORD wCookie, char* szBody, size_t nBodyLen, WORD wType)
-{
- icq_packet packet;
- packDirectMsgHeader(&packet, getPluginTypeIdLen(wType) + 11 + nBodyLen, DIRECT_ACK, wCookie, MTYPE_PLUGIN, 0, 0, 0);
-
- packEmptyMsg(&packet); // Message (unused)
-
- packPluginTypeId(&packet, wType);
-
- packLEDWord(&packet, DWORD(nBodyLen + 4));
- packLEDWord(&packet, DWORD(nBodyLen));
- packBuffer(&packet, (LPBYTE)szBody, nBodyLen);
-
- SendDirectMessage(hContact, &packet);
-}
diff --git a/protocols/IcqOscarJ/src/dlgproc.cpp b/protocols/IcqOscarJ/src/dlgproc.cpp
deleted file mode 100644
index 061538a074..0000000000
--- a/protocols/IcqOscarJ/src/dlgproc.cpp
+++ /dev/null
@@ -1,507 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2001-2004 Richard Hughes, Martin Öberg
-// Copyright © 2004-2010 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// ChangeInfo Plugin stuff
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-#define DM_PROTOACK (WM_USER+10)
-
-static int DrawTextUtf(HDC hDC, char *text, LPRECT lpRect, UINT uFormat, LPSIZE lpSize)
-{
- int res;
-
- WCHAR *tmp = make_unicode_string(text);
- res = DrawTextW(hDC, tmp, -1, lpRect, uFormat);
- if (lpSize)
- GetTextExtentPoint32W(hDC, tmp, (int)mir_wstrlen(tmp), lpSize);
- SAFE_FREE((void**)&tmp);
-
- return res;
-}
-
-char* ChangeInfoData::GetItemSettingText(int i, char *buf, size_t bufsize)
-{
- char *text = buf;
- int alloced = 0;
-
- buf[0] = '\0';
-
- const SettingItem &si = setting[i];
- SettingItemData &sid = settingData[i];
- if (sid.value == 0 && !(si.displayType & LIF_ZEROISVALID)) {
- if (si.displayType & LIF_CHANGEONLY)
- text = ICQTranslateUtfStatic(LPGEN("<unremovable once applied>"), buf, bufsize);
- else
- text = ICQTranslateUtfStatic(LPGEN("<empty>"), buf, bufsize);
- }
- else {
- switch (si.displayType & LIM_TYPE) {
- case LI_STRING:
- case LI_LONGSTRING:
- text = BinaryToEscapes((char*)sid.value);
- alloced = 1;
- break;
-
- case LI_NUMBER:
- _itoa(sid.value, text, 10);
- break;
-
- case LI_LIST:
- if (si.dbType == DBVT_ASCIIZ)
- text = ICQTranslateUtfStatic((char*)sid.value, buf, bufsize);
- else {
- text = ICQTranslateUtfStatic(LPGEN("Unknown value"), buf, bufsize);
-
- FieldNamesItem *list = (FieldNamesItem*)si.pList;
- if (list == timezonesField) {
- HANDLE tz = TimeZone_CreateByContact(NULL, ppro->m_szModuleName, 0);
- text = make_utf8_string_static(TimeZone_GetDescription(TimeZone_GetName(tz)), buf, bufsize);
- break;
- }
-
- for (int j = 0;; j++) {
- if (list[j].code == sid.value) {
- text = ICQTranslateUtfStatic(list[j].text, buf, bufsize);
- break;
- }
- else if (!list[j].text) {
- if (list[j].code == sid.value)
- text = ICQTranslateUtfStatic("Unspecified", buf, bufsize);
- break;
- }
- }
- }
- break;
- }
- }
-
- if (si.displayType & LIF_PASSWORD) {
- if (sid.changed) {
- for (int j = 0; text[j]; j++)
- text[j] = '*';
- }
- else {
- if (alloced) {
- SAFE_FREE(&text);
- alloced = 0;
- }
- text = "********";
- }
- }
- if (text != buf) {
- char *tmp = text;
-
- text = null_strcpy(buf, text, bufsize - 1);
- if (alloced)
- SAFE_FREE(&tmp);
- }
-
- return text;
-}
-
-void ChangeInfoData::PaintItemSetting(HDC hdc, RECT *rc, int i, UINT itemState)
-{
- char str[MAX_PATH];
- char *text = GetItemSettingText(i, str, _countof(str));
-
- const SettingItem &si = setting[i];
- SettingItemData &sid = settingData[i];
- if (sid.value == 0 && !(si.displayType & LIF_ZEROISVALID))
- SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
-
- if ((si.displayType & LIM_TYPE) == LI_LIST && (itemState & CDIS_SELECTED || iEditItem == i)) {
- RECT rcBtn = *rc;
- rcBtn.left = rcBtn.right - rc->bottom + rc->top;
- InflateRect(&rcBtn, -2, -2);
- rc->right = rcBtn.left;
- DrawFrameControl(hdc, &rcBtn, DFC_SCROLL, iEditItem == i ? DFCS_SCROLLDOWN | DFCS_PUSHED : DFCS_SCROLLDOWN);
- }
- DrawTextUtf(hdc, text, rc, DT_END_ELLIPSIS | DT_LEFT | DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER, nullptr);
-}
-
-static int ChangeInfoDlg_Resize(HWND, LPARAM, UTILRESIZECONTROL *urc)
-{
- switch (urc->wId) {
- case IDC_LIST:
- return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
-
- case IDC_SAVE:
- return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
-
- case IDC_UPLOADING:
- return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM;
- }
-
- return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default
-}
-
-
-INT_PTR CALLBACK ChangeInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- ChangeInfoData* dat = (ChangeInfoData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
-
- dat = new ChangeInfoData();
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
-
- dat->hwndDlg = hwndDlg;
- dat->ppro = (CIcqProto*)lParam;
- dat->hwndList = GetDlgItem(hwndDlg, IDC_LIST);
-
- ListView_SetExtendedListViewStyle(dat->hwndList, LVS_EX_FULLROWSELECT);
- dat->iEditItem = -1;
- {
- dat->hListFont = (HFONT)SendMessage(dat->hwndList, WM_GETFONT, 0, 0);
-
- LOGFONT lf;
- GetObject(dat->hListFont, sizeof(lf), &lf);
- lf.lfHeight -= 5;
- HFONT hFont = CreateFontIndirect(&lf);
- SendMessage(dat->hwndList, WM_SETFONT, (WPARAM)hFont, 0);
-
- // Prepare ListView Columns
- RECT rc;
- GetClientRect(dat->hwndList, &rc);
- rc.right -= GetSystemMetrics(SM_CXVSCROLL);
-
- LV_COLUMN lvc = { 0 };
- lvc.mask = LVCF_WIDTH;
- lvc.cx = rc.right / 3;
- ListView_InsertColumn(dat->hwndList, 0, &lvc);
- lvc.cx = rc.right - lvc.cx;
- ListView_InsertColumn(dat->hwndList, 1, &lvc);
-
- // Prepare Setting Items
- LV_ITEM lvi = { 0 };
- lvi.mask = LVIF_PARAM | LVIF_TEXT;
- for (lvi.iItem = 0; lvi.iItem < settingCount; lvi.iItem++) {
- wchar_t text[MAX_PATH];
- lvi.lParam = lvi.iItem;
- lvi.pszText = text;
- make_unicode_string_static(setting[lvi.iItem].szDescription, text, _countof(text));
- ListView_InsertItem(dat->hwndList, &lvi);
- }
- }
-
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- return TRUE;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->idFrom) {
- case 0:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_PARAMCHANGED:
- dat->ppro = (CIcqProto*)((PSHNOTIFY*)lParam)->lParam;
- dat->LoadSettingsFromDb(0);
- {
- char *pwd = dat->ppro->GetUserPassword(TRUE);
- mir_strcpy(dat->Password, (pwd) ? pwd : ""); /// FIXME
- }
- break;
-
- case PSN_INFOCHANGED:
- dat->LoadSettingsFromDb(1);
- break;
-
- case PSN_KILLACTIVE:
- dat->EndStringEdit(1);
- dat->EndListEdit(1);
- break;
-
- case PSN_APPLY:
- if (dat->ChangesMade()) {
- if (MessageBox(hwndDlg, TranslateT("You've made some changes to your ICQ details but it has not been saved to the server. Are you sure you want to close this dialog?"), TranslateT("Change ICQ Details"), MB_YESNOCANCEL) != IDYES) {
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
- return TRUE;
- }
- }
- }
- break;
-
- case IDC_LIST:
- switch (((LPNMHDR)lParam)->code) {
- case LVN_GETDISPINFO:
- if (dat->iEditItem != -1) {
- if (dat->editTopIndex != ListView_GetTopIndex(dat->hwndList)) {
- dat->EndStringEdit(1);
- dat->EndListEdit(1);
- }
- }
- break;
-
- case NM_CUSTOMDRAW:
- {
- LPNMLVCUSTOMDRAW cd = (LPNMLVCUSTOMDRAW)lParam;
-
- switch (cd->nmcd.dwDrawStage) {
- case CDDS_PREPAINT:
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW);
- return TRUE;
-
- case CDDS_ITEMPREPAINT:
- if (dat->iEditItem != -1) {
- if (dat->editTopIndex != ListView_GetTopIndex(dat->hwndList)) {
- dat->EndStringEdit(1);
- dat->EndListEdit(1);
- }
- }
- {
- RECT rcItem;
- ListView_GetItemRect(dat->hwndList, cd->nmcd.dwItemSpec, &rcItem, LVIR_BOUNDS);
-
- if (GetWindowLongPtr(dat->hwndList, GWL_STYLE) & WS_DISABLED) { // Disabled List
- SetTextColor(cd->nmcd.hdc, cd->clrText);
- FillRect(cd->nmcd.hdc, &rcItem, GetSysColorBrush(COLOR_3DFACE));
- }
- else if ((cd->nmcd.uItemState & CDIS_SELECTED || dat->iEditItem == (int)cd->nmcd.dwItemSpec)
- && setting[cd->nmcd.lItemlParam].displayType != LI_DIVIDER) { // Selected item
- SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
- FillRect(cd->nmcd.hdc, &rcItem, GetSysColorBrush(COLOR_HIGHLIGHT));
- }
- else { // Unselected item
- SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_WINDOWTEXT));
- FillRect(cd->nmcd.hdc, &rcItem, GetSysColorBrush(COLOR_WINDOW));
- }
-
- HFONT hoFont = (HFONT)SelectObject(cd->nmcd.hdc, dat->hListFont);
-
- if (setting[cd->nmcd.lItemlParam].displayType == LI_DIVIDER) {
- RECT rcLine;
- SIZE textSize;
- char str[MAX_PATH];
- char *szText = ICQTranslateUtfStatic(setting[cd->nmcd.lItemlParam].szDescription, str, MAX_PATH);
-
- SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_3DSHADOW));
- DrawTextUtf(cd->nmcd.hdc, szText, &rcItem, DT_CENTER | DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER, &textSize);
- rcLine.top = (rcItem.top + rcItem.bottom) / 2 - 1;
- rcLine.bottom = rcLine.top + 2;
- rcLine.left = rcItem.left + 3;
- rcLine.right = (rcItem.left + rcItem.right - textSize.cx) / 2 - 3;
- DrawEdge(cd->nmcd.hdc, &rcLine, BDR_SUNKENOUTER, BF_RECT);
- rcLine.left = (rcItem.left + rcItem.right + textSize.cx) / 2 + 3;
- rcLine.right = rcItem.right - 3;
- DrawEdge(cd->nmcd.hdc, &rcLine, BDR_SUNKENOUTER, BF_RECT);
- }
- else {
- RECT rcItemDescr, rcItemValue;
- char str[MAX_PATH];
-
- ListView_GetSubItemRect(dat->hwndList, cd->nmcd.dwItemSpec, 0, LVIR_BOUNDS, &rcItemDescr);
- ListView_GetSubItemRect(dat->hwndList, cd->nmcd.dwItemSpec, 1, LVIR_BOUNDS, &rcItemValue);
-
- rcItemDescr.right = rcItemValue.left;
- rcItemDescr.left += 2;
- DrawTextUtf(cd->nmcd.hdc, ICQTranslateUtfStatic(setting[cd->nmcd.lItemlParam].szDescription, str, MAX_PATH), &rcItemDescr, DT_END_ELLIPSIS | DT_LEFT | DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER, nullptr);
-
- dat->PaintItemSetting(cd->nmcd.hdc, &rcItemValue, cd->nmcd.lItemlParam, cd->nmcd.uItemState);
- }
- SelectObject(cd->nmcd.hdc, hoFont);
-
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT);
-
- return TRUE;
- }
- }
- }
- break;
-
- case NM_CLICK:
- {
- LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam;
- LV_ITEM lvi;
- RECT rc;
-
- dat->EndStringEdit(1);
- dat->EndListEdit(1);
- if (nm->iSubItem != 1) break;
- lvi.mask = LVIF_PARAM | LVIF_STATE;
- lvi.stateMask = 0xFFFFFFFF;
- lvi.iItem = nm->iItem; lvi.iSubItem = nm->iSubItem;
- ListView_GetItem(dat->hwndList, &lvi);
- if (!(lvi.state & LVIS_SELECTED)) break;
- ListView_EnsureVisible(dat->hwndList, lvi.iItem, FALSE);
- ListView_GetSubItemRect(dat->hwndList, lvi.iItem, lvi.iSubItem, LVIR_BOUNDS, &rc);
- dat->editTopIndex = ListView_GetTopIndex(dat->hwndList);
- switch (setting[lvi.lParam].displayType & LIM_TYPE) {
- case LI_STRING:
- case LI_LONGSTRING:
- case LI_NUMBER:
- dat->BeginStringEdit(nm->iItem, &rc, lvi.lParam, 0);
- break;
- case LI_LIST:
- dat->BeginListEdit(nm->iItem, &rc, lvi.lParam, 0);
- break;
- }
- }
- break;
-
- case LVN_KEYDOWN:
- {
- LPNMLVKEYDOWN nm = (LPNMLVKEYDOWN)lParam;
- LV_ITEM lvi;
- RECT rc;
-
- dat->EndStringEdit(1);
- dat->EndListEdit(1);
- if (nm->wVKey == VK_SPACE || nm->wVKey == VK_RETURN || nm->wVKey == VK_F2) nm->wVKey = 0;
- if (nm->wVKey && (nm->wVKey < '0' || (nm->wVKey > '9' && nm->wVKey < 'A') || (nm->wVKey > 'Z' && nm->wVKey < VK_NUMPAD0) || nm->wVKey >= VK_F1))
- break;
- lvi.mask = LVIF_PARAM | LVIF_STATE;
- lvi.stateMask = 0xFFFFFFFF;
- lvi.iItem = ListView_GetNextItem(dat->hwndList, -1, LVNI_ALL | LVNI_SELECTED);
- if (lvi.iItem == -1) break;
- lvi.iSubItem = 1;
- ListView_GetItem(dat->hwndList, &lvi);
- ListView_EnsureVisible(dat->hwndList, lvi.iItem, FALSE);
- ListView_GetSubItemRect(dat->hwndList, lvi.iItem, lvi.iSubItem, LVIR_BOUNDS, &rc);
- dat->editTopIndex = ListView_GetTopIndex(dat->hwndList);
- switch (setting[lvi.lParam].displayType & LIM_TYPE) {
- case LI_STRING:
- case LI_LONGSTRING:
- case LI_NUMBER:
- dat->BeginStringEdit(lvi.iItem, &rc, lvi.lParam, nm->wVKey);
- break;
- case LI_LIST:
- dat->BeginListEdit(lvi.iItem, &rc, lvi.lParam, nm->wVKey);
- break;
- }
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
- }
- return TRUE;
-
- case NM_KILLFOCUS:
- if (!IsStringEditWindow(GetFocus()))
- dat->EndStringEdit(1);
- if (!IsListEditWindow(GetFocus()))
- dat->EndListEdit(1);
- }
- }
- break;
-
- case WM_KILLFOCUS:
- dat->EndStringEdit(1);
- dat->EndListEdit(1);
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDCANCEL:
- SendMessage(GetParent(hwndDlg), msg, wParam, lParam);
- break;
-
- case IDC_SAVE:
- if (!dat->SaveSettingsToDb())
- break;
-
- EnableDlgItem(hwndDlg, IDC_SAVE, FALSE);
- EnableDlgItem(hwndDlg, IDC_LIST, FALSE);
- SetDlgItemText(hwndDlg, IDC_UPLOADING, TranslateT("Upload in progress..."));
- EnableDlgItem(hwndDlg, IDC_UPLOADING, TRUE);
- ShowDlgItem(hwndDlg, IDC_UPLOADING, SW_SHOW);
- dat->hAckHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, DM_PROTOACK);
-
- if (!dat->UploadSettings()) {
- EnableDlgItem(hwndDlg, IDC_SAVE, TRUE);
- EnableDlgItem(hwndDlg, IDC_LIST, TRUE);
- ShowDlgItem(hwndDlg, IDC_UPLOADING, SW_HIDE);
- UnhookEvent(dat->hAckHook);
- dat->hAckHook = nullptr;
- }
- }
- break;
-
- case WM_SIZE:
- if (IsIconic(hwndDlg))
- break;
-
- Utils_ResizeDialog(hwndDlg, g_plugin.getInst(), MAKEINTRESOURCEA(IDD_INFO_CHANGEINFO), ChangeInfoDlg_Resize);
- {
- RECT rc; // update listview column widths
- GetClientRect(dat->hwndList, &rc);
- rc.right -= GetSystemMetrics(SM_CXVSCROLL);
- ListView_SetColumnWidth(dat->hwndList, 0, rc.right / 3);
- ListView_SetColumnWidth(dat->hwndList, 1, rc.right - rc.right / 3);
- }
- break;
-
- case DM_PROTOACK:
- {
- ACKDATA *ack = (ACKDATA*)lParam;
- int i, done;
-
- if (ack->type != ACKTYPE_SETINFO) break;
- if (ack->result == ACKRESULT_SUCCESS) {
- for (i = 0; i < _countof(dat->hUpload); i++)
- if (dat->hUpload[i] && ack->hProcess == dat->hUpload[i])
- break;
-
- if (i == _countof(dat->hUpload)) break;
- dat->hUpload[i] = nullptr;
- for (done = 0, i = 0; i < _countof(dat->hUpload); i++)
- done += dat->hUpload[i] == nullptr;
- wchar_t buf[MAX_PATH];
- mir_snwprintf(buf, TranslateT("Upload in progress...%d%%"), 100 * done / (_countof(dat->hUpload)));
- SetDlgItemText(hwndDlg, IDC_UPLOADING, buf);
- if (done < _countof(dat->hUpload)) break;
-
- dat->ClearChangeFlags();
- UnhookEvent(dat->hAckHook);
- dat->hAckHook = nullptr;
- EnableDlgItem(hwndDlg, IDC_LIST, TRUE);
- EnableDlgItem(hwndDlg, IDC_UPLOADING, FALSE);
- SetDlgItemText(hwndDlg, IDC_UPLOADING, TranslateT("Upload complete"));
- SendMessage(GetParent(hwndDlg), PSM_FORCECHANGED, 0, 0);
- }
- else if (ack->result == ACKRESULT_FAILED) {
- UnhookEvent(dat->hAckHook);
- dat->hAckHook = nullptr;
- EnableDlgItem(hwndDlg, IDC_LIST, TRUE);
- EnableDlgItem(hwndDlg, IDC_UPLOADING, FALSE);
- SetDlgItemText(hwndDlg, IDC_UPLOADING, TranslateT("Upload FAILED"));
- SendMessage(GetParent(hwndDlg), PSM_FORCECHANGED, 0, 0);
- EnableDlgItem(hwndDlg, IDC_SAVE, TRUE);
- }
- }
- break;
-
- case WM_DESTROY:
- if (dat->hAckHook) {
- UnhookEvent(dat->hAckHook);
- dat->hAckHook = nullptr;
- }
-
- DeleteObject((HFONT)SendMessage(dat->hwndList, WM_GETFONT, 0, 0));
-
- dat->FreeStoredDbSettings();
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
- delete dat;
- break;
- }
- return FALSE;
-}
diff --git a/protocols/IcqOscarJ/src/editlist.cpp b/protocols/IcqOscarJ/src/editlist.cpp
deleted file mode 100644
index 165e09bf7f..0000000000
--- a/protocols/IcqOscarJ/src/editlist.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2001-2004 Richard Hughes, Martin Öberg
-// Copyright © 2004-2009 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// ChangeInfo Plugin stuff
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-static ChangeInfoData *dataListEdit = nullptr;
-static HWND hwndListEdit = nullptr;
-
-static LRESULT CALLBACK ListEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case WM_LBUTTONUP:
- mir_callNextSubclass(hwnd, ListEditSubclassProc, msg, wParam, lParam);
- {
- POINT pt = { (short)LOWORD(lParam), (short)HIWORD(lParam) };
- ClientToScreen(hwnd, &pt);
- if (SendMessage(hwnd, WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y)) == HTVSCROLL)
- break;
-
- int i = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
- if (dataListEdit)
- dataListEdit->EndListEdit(i != LB_ERR);
- }
- return 0;
-
- case WM_CHAR:
- if (wParam != '\r') break;
- {
- int i = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
- if (dataListEdit)
- dataListEdit->EndListEdit(i != LB_ERR);
- }
- return 0;
-
- case WM_KILLFOCUS:
- if (dataListEdit)
- dataListEdit->EndListEdit(1);
- return 0;
- }
- return mir_callNextSubclass(hwnd, ListEditSubclassProc, msg, wParam, lParam);
-}
-
-void ChangeInfoData::BeginListEdit(int iItem, RECT *rc, int iSetting, WORD wVKey)
-{
- if (dataListEdit)
- dataListEdit->EndListEdit(0);
-
- POINT pt = { 0, 0 };
- ClientToScreen(hwndList, &pt);
- OffsetRect(rc, pt.x, pt.y);
- InflateRect(rc, -2, -2);
- rc->left -= 2;
- iEditItem = iItem;
- ListView_RedrawItems(hwndList, iEditItem, iEditItem);
- UpdateWindow(hwndList);
-
- dataListEdit = this;
- hwndListEdit = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, L"LISTBOX", L"", WS_POPUP | WS_BORDER | WS_VSCROLL,
- rc->left, rc->bottom, rc->right - rc->left, 150, nullptr, nullptr, g_plugin.getInst(), nullptr);
- SendMessage(hwndListEdit, WM_SETFONT, (WPARAM)hListFont, 0);
- int itemHeight = SendMessage(hwndListEdit, LB_GETITEMHEIGHT, 0, 0);
-
- const SettingItem &si = setting[iSetting];
- SettingItemData &sid = settingData[iSetting];
- FieldNamesItem *list = (FieldNamesItem*)si.pList;
-
- // some country codes were changed leaving old details uknown, convert it for the user
- if (list == countryField) {
- if (sid.value == 420)
- sid.value = 42; // conversion of obsolete codes (OMG!)
- else if (sid.value == 421)
- sid.value = 4201;
- else if (sid.value == 102)
- sid.value = 1201;
- }
-
- if (list == timezonesField) {
- TimeZone_PrepareList(NULL, ppro->m_szModuleName, hwndListEdit, TZF_PLF_LB);
- }
- else {
- int j, n = ListBoxAddStringUtf(hwndListEdit, "Unspecified");
- for (j = 0;; j++)
- if (!list[j].text) {
- SendMessage(hwndListEdit, LB_SETITEMDATA, n, j);
- if ((sid.value == 0 && list[j].code == 0) || (si.dbType != DBVT_ASCIIZ && sid.value == list[j].code))
- SendMessage(hwndListEdit, LB_SETCURSEL, n, 0);
- break;
- }
-
- for (j = 0; list[j].text; j++) {
- char str[MAX_PATH];
- n = ListBoxAddStringUtf(hwndListEdit, list[j].text);
- SendMessage(hwndListEdit, LB_SETITEMDATA, n, j);
- if ((si.dbType == DBVT_ASCIIZ && (!mir_strcmp((char*)sid.value, list[j].text))
- || (si.dbType == DBVT_ASCIIZ && (!mir_strcmp((char*)sid.value, ICQTranslateUtfStatic(list[j].text, str, MAX_PATH))))
- || ((char*)sid.value == nullptr && list[j].code == 0))
- || (si.dbType != DBVT_ASCIIZ && sid.value == list[j].code))
- SendMessage(hwndListEdit, LB_SETCURSEL, n, 0);
- }
- SendMessage(hwndListEdit, LB_SETTOPINDEX, SendMessage(hwndListEdit, LB_GETCURSEL, 0, 0) - 3, 0);
- }
-
- int listCount = SendMessage(hwndListEdit, LB_GETCOUNT, 0, 0);
- if (itemHeight * listCount < 150)
- SetWindowPos(hwndListEdit, nullptr, 0, 0, rc->right - rc->left, itemHeight * listCount + GetSystemMetrics(SM_CYBORDER) * 2, SWP_NOZORDER | SWP_NOMOVE);
- mir_subclassWindow(hwndListEdit, ListEditSubclassProc);
- AnimateWindow(hwndListEdit, 200, AW_SLIDE | AW_ACTIVATE | AW_VER_POSITIVE);
- ShowWindow(hwndListEdit, SW_SHOW);
- SetFocus(hwndListEdit);
- if (wVKey)
- PostMessage(hwndListEdit, WM_KEYDOWN, wVKey, 0);
-}
-
-void ChangeInfoData::EndListEdit(int save)
-{
- if (hwndListEdit == nullptr || iEditItem == -1 || this != dataListEdit)
- return;
-
- if (save) {
- const SettingItem &si = setting[iEditItem];
- SettingItemData &sid = settingData[iEditItem];
-
- int iItem = SendMessage(hwndListEdit, LB_GETCURSEL, 0, 0);
- int i = SendMessage(hwndListEdit, LB_GETITEMDATA, iItem, 0);
- if (iItem != -1 && i != -1) {
- FieldNamesItem *list = (FieldNamesItem*)si.pList;
- if (list == timezonesField) {
- TimeZone_StoreListResult(NULL, ppro->m_szModuleName, hwndListEdit, TZF_PLF_LB);
- list[i = 0].code = ppro->getDword("Timezone", 0);
- }
-
- FieldNamesItem &pItem = list[i];
-
- if (si.dbType == DBVT_ASCIIZ) {
- char *szNewValue = pItem.text;
- if (pItem.code || (si.displayType & LIF_ZEROISVALID)) {
- sid.changed = mir_strcmp(szNewValue, (char*)sid.value);
- SAFE_FREE((void**)&sid.value);
- sid.value = (LPARAM)null_strdup(szNewValue);
- }
- else {
- sid.changed = (char*)sid.value != nullptr;
- SAFE_FREE((void**)&sid.value);
- }
- }
- else {
- sid.changed = pItem.code != sid.value;
- sid.value = pItem.code;
- }
-
- if (sid.changed) {
- char buf[MAX_PATH];
- wchar_t tbuf[MAX_PATH];
- if (make_unicode_string_static(ICQTranslateUtfStatic(pItem.text, buf, _countof(buf)), tbuf, _countof(buf)))
- ListView_SetItemText(hwndList, iEditItem, 1, tbuf);
-
- EnableDlgItem(GetParent(hwndList), IDC_SAVE, TRUE);
- }
- }
- }
- ListView_RedrawItems(hwndList, iEditItem, iEditItem);
- iEditItem = -1;
- dataListEdit = nullptr;
- DestroyWindow(hwndListEdit);
- hwndListEdit = nullptr;
-}
-
-int IsListEditWindow(HWND hwnd)
-{
- if (hwnd == hwndListEdit) return 1;
- return 0;
-}
diff --git a/protocols/IcqOscarJ/src/editstring.cpp b/protocols/IcqOscarJ/src/editstring.cpp
deleted file mode 100644
index ef689445da..0000000000
--- a/protocols/IcqOscarJ/src/editstring.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2001-2004 Richard Hughes, Martin Öberg
-// Copyright © 2004-2009 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// ChangeInfo Plugin stuff
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-static ChangeInfoData *dataStringEdit = nullptr;
-static HWND hwndEdit = nullptr, hwndExpandButton = nullptr, hwndUpDown = nullptr;
-
-static const char escapes[] =
-{
- 'a','\a',
- 'b','\b',
- 'e',27,
- 'f','\f',
- 'r','\r',
- 't','\t',
- 'v','\v',
- '\\','\\'
-};
-
-static void EscapesToMultiline(WCHAR *str, PDWORD selStart, PDWORD selEnd)
-{
- // converts "\\n" and "\\t" to "\r\n" and "\t" because a multi-line edit box can show them properly
- DWORD i;
-
- for (i = 0; *str; str++, i++) {
- if (*str != '\\') continue;
- if (str[1] == 'n') {
- *str++ = '\r';
- i++;
- *str = '\n';
- }
- else if (str[1] == 't') {
- *str = '\t';
- memmove(str + 1, str + 2, sizeof(WCHAR)*(mir_wstrlen(str) - 1));
-
- if (*selStart > i)--*selStart;
- if (*selEnd > i)--*selEnd;
- }
- }
-}
-
-static void EscapesToBinary(char *str)
-{
- for (; *str; str++) {
- if (*str != '\\') continue;
- if (str[1] == 'n') { *str++ = '\r'; *str = '\n'; continue; }
- if (str[1] == '0') {
- char *codeend;
- *str = (char)strtol(str + 1, &codeend, 8);
- if (*str == 0) { *str = '\\'; continue; }
- memmove(str + 1, codeend, mir_strlen(codeend) + 1);
- continue;
- }
- for (int i = 0; i < _countof(escapes); i += 2)
- if (str[1] == escapes[i]) {
- *str = escapes[i + 1];
- memmove(str + 1, str + 2, mir_strlen(str) - 1);
- break;
- }
- }
-}
-
-char *BinaryToEscapes(char *str)
-{
- int extra = 10, len = (int)mir_strlen(str) + 11, i;
- char *out, *pout;
-
- out = pout = (char*)SAFE_MALLOC(len);
- for (; *str; str++) {
- if ((unsigned char)*str >= ' ') {
- *pout++ = *str;
- continue;
- }
- if (str[0] == '\r' && str[1] == '\n') {
- *pout++ = '\\';
- *pout++ = 'n';
- str++;
- continue;
- }
- if (extra < 3) {
- extra += 8; len += 8;
- pout = out = (char*)SAFE_REALLOC(out, len);
- }
- *pout++ = '\\';
- for (i = 0; i < _countof(escapes); i += 2)
- if (*str == escapes[i + 1]) {
- *pout++ = escapes[i];
- extra--;
- break;
- }
- if (i < _countof(escapes)) continue;
- *pout++ = '0'; extra--;
- if (*str >= 8) {
- *pout++ = (*str >> 3) + '0';
- extra--;
- }
- *pout++ = (*str & 7) + '0'; extra--;
- }
- *pout = '\0';
- return out;
-}
-
-static LRESULT CALLBACK StringEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case WM_KEYDOWN:
- if (wParam == VK_ESCAPE) {
- if (dataStringEdit)
- dataStringEdit->EndStringEdit(0);
- return 0;
- }
- if (wParam == VK_RETURN) {
- if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_MULTILINE && !(GetKeyState(VK_CONTROL) & 0x8000)) break;
- if (dataStringEdit)
- dataStringEdit->EndStringEdit(1);
- return 0;
- }
- break;
-
- case WM_GETDLGCODE:
- return DLGC_WANTALLKEYS | mir_callNextSubclass(hwnd, StringEditSubclassProc, msg, wParam, lParam);
-
- case WM_KILLFOCUS:
- if ((HWND)wParam == hwndExpandButton) break;
- if (dataStringEdit)
- dataStringEdit->EndStringEdit(1);
- return 0;
- }
- return mir_callNextSubclass(hwnd, StringEditSubclassProc, msg, wParam, lParam);
-}
-
-static LRESULT CALLBACK ExpandButtonSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case WM_LBUTTONUP:
- if (GetCapture() == hwnd) {
- //do expand
- RECT rcStart, rcEnd;
- DWORD selStart, selEnd;
- WCHAR *text;
- BOOL animEnabled = TRUE;
-
- GetWindowRect(hwndEdit, &rcStart);
- InflateRect(&rcStart, 2, 2);
-
- text = GetWindowTextUcs(hwndEdit);
- SendMessage(hwndEdit, EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd);
- DestroyWindow(hwndEdit);
- EscapesToMultiline(text, &selStart, &selEnd);
- hwndEdit = CreateWindowExA(WS_EX_TOOLWINDOW, "EDIT", "", WS_POPUP | WS_BORDER | WS_VISIBLE | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL | ES_MULTILINE, rcStart.left, rcStart.top, rcStart.right - rcStart.left, rcStart.bottom - rcStart.top, nullptr, nullptr, g_plugin.getInst(), nullptr);
- SetWindowTextUcs(hwndEdit, text);
- mir_subclassWindow(hwndEdit, StringEditSubclassProc);
- SendMessage(hwndEdit, WM_SETFONT, (WPARAM)dataStringEdit->hListFont, 0);
- SendMessage(hwndEdit, EM_SETSEL, selStart, selEnd);
- SetFocus(hwndEdit);
-
- rcEnd.left = rcStart.left; rcEnd.top = rcStart.top;
- rcEnd.right = rcEnd.left + 350;
- rcEnd.bottom = rcEnd.top + 150;
- if (LOBYTE(LOWORD(GetVersion())) > 4 || HIBYTE(LOWORD(GetVersion())) > 0)
- SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &animEnabled, FALSE);
- if (animEnabled) {
- DWORD startTime, timeNow;
- startTime = GetTickCount();
- for (;;) {
- UpdateWindow(hwndEdit);
- timeNow = GetTickCount();
- if (timeNow > startTime + 200) break;
- SetWindowPos(hwndEdit, nullptr, rcEnd.left, rcEnd.top, (rcEnd.right - rcStart.right)*(timeNow - startTime) / 200 + rcStart.right - rcEnd.left, (rcEnd.bottom - rcStart.bottom)*(timeNow - startTime) / 200 + rcStart.bottom - rcEnd.top, SWP_NOZORDER);
- }
- }
- SetWindowPos(hwndEdit, nullptr, rcEnd.left, rcEnd.top, rcEnd.right - rcEnd.left, rcEnd.bottom - rcEnd.top, SWP_NOZORDER);
-
- DestroyWindow(hwnd);
- hwndExpandButton = nullptr;
-
- SAFE_FREE((void**)&text);
- }
- break;
- }
- return mir_callNextSubclass(hwnd, ExpandButtonSubclassProc, msg, wParam, lParam);
-}
-
-void ChangeInfoData::BeginStringEdit(int iItem, RECT *rc, int i, WORD wVKey)
-{
- char *szValue;
- char str[80];
- int alloced = 0;
-
- EndStringEdit(0);
- InflateRect(rc, -2, -2);
- rc->left -= 2;
-
- const SettingItem &si = setting[i];
- SettingItemData &sid = settingData[i];
-
- if (si.displayType & LIF_PASSWORD && !sid.changed)
- szValue = " ";
- else if ((si.displayType & LIM_TYPE) == LI_NUMBER) {
- szValue = str;
- mir_snprintf(str, "%d", sid.value);
- }
- else if (sid.value) {
- szValue = BinaryToEscapes((char*)sid.value);
- alloced = 1;
- }
- else szValue = "";
-
- iEditItem = iItem;
-
- if ((si.displayType & LIM_TYPE) == LI_LONGSTRING) {
- rc->right -= rc->bottom - rc->top;
- hwndExpandButton = CreateWindowA("BUTTON", "", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_ICON, rc->right, rc->top, rc->bottom - rc->top, rc->bottom - rc->top, hwndList, nullptr, g_plugin.getInst(), nullptr);
- SendMessage(hwndExpandButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIconByHandle(iconList[0].hIcolib));
- mir_subclassWindow(hwndExpandButton, ExpandButtonSubclassProc);
- }
-
- dataStringEdit = this;
- hwndEdit = CreateWindow(L"EDIT", L"", WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL | ((si.displayType&LIM_TYPE) == LI_NUMBER ? ES_NUMBER : 0) | (si.displayType&LIF_PASSWORD ? ES_PASSWORD : 0), rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, hwndList, nullptr, g_plugin.getInst(), nullptr);
- SetWindowTextUtf(hwndEdit, szValue);
- if (alloced) SAFE_FREE(&szValue);
- mir_subclassWindow(hwndEdit, StringEditSubclassProc);
- SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hListFont, 0);
- if ((si.displayType & LIM_TYPE) == LI_NUMBER) {
- int *range = (int*)si.pList;
- RECT rcUpDown;
- hwndUpDown = CreateWindow(UPDOWN_CLASS, L"", WS_VISIBLE | WS_CHILD | UDS_AUTOBUDDY | UDS_ALIGNRIGHT | UDS_HOTTRACK | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 0, 0, 0, 0, hwndList, nullptr, g_plugin.getInst(), nullptr);
- SendMessage(hwndUpDown, UDM_SETRANGE32, range[0], range[1]);
- SendMessage(hwndUpDown, UDM_SETPOS32, 0, sid.value);
- if (!(si.displayType & LIF_ZEROISVALID) && sid.value == 0)
- SetWindowTextA(hwndEdit, "");
- GetClientRect(hwndUpDown, &rcUpDown);
- rc->right -= rcUpDown.right;
- SetWindowPos(hwndEdit, nullptr, 0, 0, rc->right - rc->left, rc->bottom - rc->top, SWP_NOZORDER | SWP_NOMOVE);
- }
- SendMessage(hwndEdit, EM_SETSEL, 0, (LPARAM)-1);
- SetFocus(hwndEdit);
- PostMessage(hwndEdit, WM_KEYDOWN, wVKey, 0);
-}
-
-void ChangeInfoData::EndStringEdit(int save)
-{
- if (hwndEdit == nullptr || iEditItem == -1 || this != dataStringEdit)
- return;
-
- if (save) {
- char *text = (char*)SAFE_MALLOC(GetWindowTextLength(hwndEdit) + 1);
- const SettingItem &si = setting[iEditItem];
- SettingItemData &sid = settingData[iEditItem];
-
- GetWindowTextA(hwndEdit, (char*)text, GetWindowTextLength(hwndEdit) + 1);
- EscapesToBinary(text);
- if ((si.displayType & LIM_TYPE) == LI_NUMBER) {
- LPARAM newValue;
- int *range = (int*)si.pList;
- newValue = atoi(text);
- if (newValue) {
- if (newValue < range[0]) newValue = range[0];
- if (newValue > range[1]) newValue = range[1];
- }
- sid.changed = sid.value != newValue;
- sid.value = newValue;
- SAFE_FREE(&text);
- }
- else {
- if (!(si.displayType & LIF_PASSWORD)) {
- SAFE_FREE(&text);
- text = GetWindowTextUtf(hwndEdit);
- EscapesToBinary(text);
- }
- if ((si.displayType & LIF_PASSWORD && mir_strcmp(text, " ")) ||
- (!(si.displayType & LIF_PASSWORD) && mir_strcmp(text, (char*)sid.value) && (mir_strlen(text) + mir_strlen((char*)sid.value)))) {
- SAFE_FREE((void**)&sid.value);
- if (mir_strlen(text))
- sid.value = (LPARAM)text;
- else {
- sid.value = 0;
- SAFE_FREE(&text);
- }
- sid.changed = 1;
- }
- }
-
- if (sid.changed) {
- wchar_t tbuf[MAX_PATH];
-
- GetWindowText(hwndEdit, tbuf, _countof(tbuf));
- ListView_SetItemText(hwndList, iEditItem, 1, tbuf);
-
- EnableDlgItem(hwndDlg, IDC_SAVE, TRUE);
- }
- }
-
- ListView_RedrawItems(hwndList, iEditItem, iEditItem);
- iEditItem = -1;
- dataStringEdit = nullptr;
- DestroyWindow(hwndEdit);
- hwndEdit = nullptr;
- if (hwndExpandButton) DestroyWindow(hwndExpandButton);
- hwndExpandButton = nullptr;
- if (hwndUpDown) DestroyWindow(hwndUpDown);
- hwndUpDown = nullptr;
-}
-
-int IsStringEditWindow(HWND hwnd)
-{
- if (hwnd == hwndEdit) return 1;
- if (hwnd == hwndExpandButton) return 1;
- if (hwnd == hwndUpDown) return 1;
- return 0;
-}
diff --git a/protocols/IcqOscarJ/src/fam_01service.cpp b/protocols/IcqOscarJ/src/fam_01service.cpp
deleted file mode 100644
index e9a1048e8a..0000000000
--- a/protocols/IcqOscarJ/src/fam_01service.cpp
+++ /dev/null
@@ -1,856 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Handles packets from Service family
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-extern capstr capXStatus[];
-
-void CIcqProto::handleServiceFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info)
-{
- icq_packet packet;
-
- switch (pSnacHeader->wSubtype) {
-
- case ICQ_SERVER_READY:
- debugLogA("Server is ready and is requesting my Family versions");
- debugLogA("Sending my Families");
-
- // This packet is a response to SRV_FAMILIES SNAC(1,3).
- // This tells the server which SNAC families and their corresponding
- // versions which the client understands. This also seems to identify
- // the client as an ICQ vice AIM client to the server.
- // Miranda mimics the behaviour of ICQ 6
- serverPacketInit(&packet, 54);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_FAMILIES);
- packDWord(&packet, 0x00220001);
- packDWord(&packet, 0x00010004);
- packDWord(&packet, 0x00130004);
- packDWord(&packet, 0x00020001);
- packDWord(&packet, 0x00030001);
- packDWord(&packet, 0x00150001);
- packDWord(&packet, 0x00040001);
- packDWord(&packet, 0x00060001);
- packDWord(&packet, 0x00090001);
- packDWord(&packet, 0x000a0001);
- packDWord(&packet, 0x000b0001);
- sendServPacket(&packet);
- break;
-
- case ICQ_SERVER_FAMILIES2:
- /* This is a reply to CLI_FAMILIES and it tells the client which families and their versions that this server understands.
- * We send a rate request packet */
- debugLogA("Server told me his Family versions");
- debugLogA("Requesting Rate Information");
-
- serverPacketInit(&packet, 10);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_REQ_RATE_INFO);
- sendServPacket(&packet);
- break;
-
- case ICQ_SERVER_RATE_INFO:
- debugLogA("Server sent Rate Info");
-
- /* init rates management */
- m_rates = new rates(this, pBuffer, wBufferLength);
-
- /* ack rate levels */
- debugLogA("Sending Rate Info Ack");
-
- m_rates->initAckPacket(&packet);
- sendServPacket(&packet);
-
- /* CLI_REQINFO - This command requests from the server certain information about the client that is stored on the server. */
- debugLogA("Sending CLI_REQINFO");
-
- serverPacketInit(&packet, 10);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_REQINFO);
- sendServPacket(&packet);
-
- if (m_bSsiEnabled) {
- cookie_servlist_action* ack;
- DWORD dwCookie;
-
- DWORD dwLastUpdate = getDword("SrvLastUpdate", 0);
- WORD wRecordCount = getWord("SrvRecordCount", 0);
-
- // CLI_REQLISTS - we want to use SSI
- debugLogA("Requesting roster rights");
-
- serverPacketInit(&packet, 16);
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_REQLISTS);
- packTLVWord(&packet, 0x0B, 0x000F); // mimic ICQ 6
- sendServPacket(&packet);
-
- if (!wRecordCount) { // CLI_REQROSTER
- // we do not have any data - request full list
- debugLogA("Requesting full roster");
-
- serverPacketInit(&packet, 10);
- ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (ack) { // we try to use standalone cookie if available
- ack->dwAction = SSA_CHECK_ROSTER; // loading list
- dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_CLI_REQUEST, 0, ack);
- }
- else // if not use that old fake
- dwCookie = ICQ_LISTS_CLI_REQUEST << 0x10;
-
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_REQUEST, 0, dwCookie);
- sendServPacket(&packet);
- }
- else { // CLI_CHECKROSTER
- debugLogA("Requesting roster check");
-
- serverPacketInit(&packet, 16);
- ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (ack) { // TODO: rewrite - use get list service for empty list
- // we try to use standalone cookie if available
- ack->dwAction = SSA_CHECK_ROSTER; // loading list
- dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_CLI_CHECK, 0, ack);
- }
- else // if not use that old fake
- dwCookie = ICQ_LISTS_CLI_CHECK << 0x10;
-
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_CHECK, 0, dwCookie);
- // check if it was not changed elsewhere (force reload, set that setting to zero)
- if (IsServerGroupsDefined()) {
- packDWord(&packet, dwLastUpdate); // last saved time
- packWord(&packet, wRecordCount); // number of records saved
- }
- else { // we need to get groups info into DB, force receive list
- packDWord(&packet, 0); // last saved time
- packWord(&packet, 0); // number of records saved
- }
- sendServPacket(&packet);
- }
- }
-
- // CLI_REQLOCATION
- debugLogA("Requesting Location rights");
-
- serverPacketInit(&packet, 10);
- packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_CLI_REQ_RIGHTS);
- sendServPacket(&packet);
-
- // CLI_REQBUDDY
- debugLogA("Requesting Client-side contactlist rights");
-
- serverPacketInit(&packet, 16);
- packFNACHeader(&packet, ICQ_BUDDY_FAMILY, ICQ_USER_CLI_REQBUDDY);
- // Query flags: 1 = Enable Avatars
- // 2 = Enable offline status message notification
- // 4 = Enable Avatars for offline contacts
- // 8 = Use reject for not authorized contacts
- packTLVWord(&packet, 0x05, 0x0007);
- sendServPacket(&packet);
-
- // CLI_REQICBM
- debugLogA("Sending CLI_REQICBM");
-
- serverPacketInit(&packet, 10);
- packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_CLI_REQICBM);
- sendServPacket(&packet);
-
- // CLI_REQBOS
- debugLogA("Sending CLI_REQBOS");
-
- serverPacketInit(&packet, 10);
- packFNACHeader(&packet, ICQ_BOS_FAMILY, ICQ_PRIVACY_REQ_RIGHTS);
- sendServPacket(&packet);
- break;
-
- case ICQ_SERVER_PAUSE:
- debugLogA("Server is going down in a few seconds... (Flags: %u)", pSnacHeader->wFlags);
- // This is the list of groups that we want to have on the next server
- serverPacketInit(&packet, 30);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_PAUSE_ACK);
- packWord(&packet, ICQ_SERVICE_FAMILY);
- packWord(&packet, ICQ_LISTS_FAMILY);
- packWord(&packet, ICQ_LOCATION_FAMILY);
- packWord(&packet, ICQ_BUDDY_FAMILY);
- packWord(&packet, ICQ_EXTENSIONS_FAMILY);
- packWord(&packet, ICQ_MSG_FAMILY);
- packWord(&packet, 0x06);
- packWord(&packet, ICQ_BOS_FAMILY);
- packWord(&packet, ICQ_LOOKUP_FAMILY);
- packWord(&packet, ICQ_STATS_FAMILY);
- sendServPacket(&packet);
-
- debugLogA("Sent server pause ack");
- break;
-
- case ICQ_SERVER_MIGRATIONREQ:
- debugLogA("Server migration requested (Flags: %u)", pSnacHeader->wFlags);
-
- pBuffer += 2; // Unknown, seen: 0
- wBufferLength -= 2;
- {
- oscar_tlv_chain *chain = readIntoTLVChain(&pBuffer, wBufferLength, 0);
-
- if (info->cookieDataLen > 0)
- SAFE_FREE((void**)&info->cookieData);
-
- info->newServer = chain->getString(0x05, 1);
- info->newServerSSL = chain->getNumber(0x8E, 1);
- info->cookieData = (BYTE*)chain->getString(0x06, 1);
- info->cookieDataLen = chain->getLength(0x06, 1);
-
- disposeChain(&chain);
-
- if (!info->newServer || !info->cookieData) {
- icq_LogMessage(LOG_FATAL, LPGEN("A server migration has failed because the server returned invalid data. You must reconnect manually."));
- SAFE_FREE(&info->newServer);
- SAFE_FREE((void**)&info->cookieData);
- info->cookieDataLen = 0;
- info->isNewServerReady = false;
- return;
- }
-
- debugLogA("Migration has started. New server will be %s", info->newServer);
-
- m_iDesiredStatus = m_iStatus;
- SetCurrentStatus(ID_STATUS_CONNECTING); // revert to connecting state
-
- info->isNewServerReady = info->isMigrating = true;
- }
- break;
-
- case ICQ_SERVER_NAME_INFO: // This is the reply to CLI_REQINFO
- debugLogA("Received self info");
- {
- BYTE bUinLen;
- unpackByte(&pBuffer, &bUinLen);
- pBuffer += bUinLen;
- pBuffer += 4; /* warning level & user class */
- wBufferLength -= 5 + bUinLen;
-
- // This is during the login sequence
- if (pSnacHeader->dwRef == ICQ_CLIENT_REQINFO << 0x10) {
- // TLV(x01) User type?
- // TLV(x0C) Empty CLI2CLI Direct connection info
- // TLV(x0A) External IP
- // TLV(x0F) Number of seconds that user has been online
- // TLV(x03) The online since time.
- // TLV(x0A) External IP again
- // TLV(x22) Unknown
- // TLV(x1E) Unknown: empty.
- // TLV(x05) Member of ICQ since.
- // TLV(x14) Unknown
- oscar_tlv_chain *chain = readIntoTLVChain(&pBuffer, wBufferLength, 0);
-
- // Save external IP
- DWORD dwValue = chain->getDWord(0x0A, 1);
- setDword("IP", dwValue);
-
- // Save member since timestamp
- dwValue = chain->getDWord(0x05, 1);
- if (dwValue) setDword("MemberTS", dwValue);
-
- dwValue = chain->getDWord(0x03, 1);
- setDword("LogonTS", dwValue ? dwValue : time(0));
-
- disposeChain(&chain);
-
- // If we are in SSI mode, this is sent after the list is acked instead
- // to make sure that we don't set status before seing the visibility code
- if (!m_bSsiEnabled || info->isMigrating)
- handleServUINSettings(wListenPort, info);
- }
- }
- break;
-
- case ICQ_SERVER_RATE_CHANGE:
- if (wBufferLength >= 2) {
- WORD wStatus, wClass;
- DWORD dwLevel;
- // We now have global rate management, although controlled are only some
- // areas. This should not arrive in most cases. If it does, update our
- // local rate levels & issue broadcast.
- unpackWord(&pBuffer, &wStatus);
- unpackWord(&pBuffer, &wClass);
- pBuffer += 20;
- unpackDWord(&pBuffer, &dwLevel);
- {
- mir_cslock l(m_ratesMutex);
- m_rates->updateLevel(wClass, dwLevel);
- }
-
- if (wStatus == 2 || wStatus == 3) {
- // this is only the simplest solution, needs rate management to every section
- ProtoBroadcastAck(NULL, ICQACKTYPE_RATEWARNING, ACKRESULT_STATUS, (HANDLE)wClass, wStatus);
- if (wStatus == 2)
- debugLogA("Rates #%u: Alert", wClass);
- else
- debugLogA("Rates #%u: Limit", wClass);
- }
- else if (wStatus == 4) {
- ProtoBroadcastAck(NULL, ICQACKTYPE_RATEWARNING, ACKRESULT_STATUS, (HANDLE)wClass, wStatus);
- debugLogA("Rates #%u: Clear", wClass);
- }
- }
-
- break;
-
- case ICQ_SERVER_REDIRECT_SERVICE: // reply to family request, got new connection point
- {
- oscar_tlv_chain *pChain = nullptr;
- cookie_family_request *pCookieData;
-
- if (!(pChain = readIntoTLVChain(&pBuffer, wBufferLength, 0))) {
- debugLogA("Received Broken Redirect Service SNAC(1,5).");
- break;
- }
-
- // pick request data
- WORD wFamily = pChain->getWord(0x0D, 1);
- if ((!FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookieData)) || (pCookieData->wFamily != wFamily)) {
- disposeChain(&pChain);
- debugLogA("Received unexpected SNAC(1,5), skipping.");
- break;
- }
-
- FreeCookie(pSnacHeader->dwRef);
-
- // new family entry point received
- char *pServer = pChain->getString(0x05, 1);
- BYTE bServerSSL = pChain->getNumber(0x8E, 1);
- char *pCookie = pChain->getString(0x06, 1);
- WORD wCookieLen = pChain->getLength(0x06, 1);
-
- if (!pServer || !pCookie) {
- debugLogA("Server returned invalid data, family unavailable.");
-
- SAFE_FREE(&pServer);
- SAFE_FREE(&pCookie);
- SAFE_FREE((void**)&pCookieData);
- disposeChain(&pChain);
- break;
- }
-
- // Get new family server ip and port
- WORD wPort = info->wServerPort; // get default port
- parseServerAddress(pServer, &wPort);
-
- // establish connection
- NETLIBOPENCONNECTION nloc = { 0 };
- if (m_bGatewayMode)
- nloc.flags |= NLOCF_HTTPGATEWAY;
- nloc.szHost = pServer;
- nloc.wPort = wPort;
-
- HNETLIBCONN hConnection = NetLib_OpenConnection(m_hNetlibUser, wFamily == ICQ_AVATAR_FAMILY ? "Avatar " : nullptr, &nloc);
-
- if (hConnection == nullptr)
- debugLogA("Unable to connect to ICQ new family server.");
- // we want the handler to be called even if the connecting failed
- else if (bServerSSL) { /* Start SSL session if requested */
- debugLogA("(%p) Starting SSL negotiation", Netlib_GetSocket(hConnection));
-
- if (!Netlib_StartSsl(hConnection, nullptr)) {
- debugLogA("Unable to connect to ICQ new family server, SSL could not be negotiated");
- NetLib_CloseConnection(&hConnection, FALSE);
- }
- }
-
- (this->*pCookieData->familyHandler)(hConnection, pCookie, wCookieLen);
-
- // Free allocated memory
- // NOTE: "cookie" will get freed when we have connected to the avatar server.
- disposeChain(&pChain);
- SAFE_FREE(&pServer);
- SAFE_FREE((void**)&pCookieData);
- break;
- }
-
- case ICQ_SERVER_EXTSTATUS: // our session data
- debugLogA("Received owner session data.");
-
- while (wBufferLength > 4) { // loop thru all items
- WORD itemType = pBuffer[0] * 0x10 | pBuffer[1];
- BYTE itemFlags = pBuffer[2];
- size_t itemLen = pBuffer[3];
-
- if (itemType == AVATAR_HASH_PHOTO) { /// TODO: handle photo item
- // skip photo item
- debugLogA("Photo item recognized");
- }
- else if ((itemType == AVATAR_HASH_STATIC || itemType == AVATAR_HASH_FLASH) && (itemLen >= 0x10)) {
- debugLogA("Avatar item recognized");
-
- if (m_bAvatarsEnabled && !info->bMyAvatarInited) { // signal the server after login
- // this refreshes avatar state - it used to work automatically, but now it does not
- if (getByte("ForceOurAvatar", 0)) { // keep our avatar
- wchar_t *file = GetOwnAvatarFileName();
- SetMyAvatar(0, (LPARAM)file);
- SAFE_FREE(&file);
- }
- else { // only change avatar hash to the same one
- BYTE hash[0x14];
- memcpy(hash, pBuffer, 0x14);
- hash[2] = 1; // update image status
- updateServAvatarHash(hash, 0x14);
- }
- info->bMyAvatarInited = true;
- break;
- }
- // process owner avatar hash changed notification
- handleAvatarOwnerHash(itemFlags, pBuffer, itemLen + 4);
- }
- else if (itemType == 0x02) {
- debugLogA("Status message item recognized");
- }
- else if (itemType == 0x0E) {
- debugLogA("Status mood item recognized");
- }
-
- // move to next item
- if (wBufferLength >= itemLen + 4) {
- wBufferLength -= itemLen + 4;
- pBuffer += itemLen + 4;
- }
- else {
- pBuffer += wBufferLength;
- wBufferLength = 0;
- }
- }
- break;
-
- case ICQ_ERROR: // Something went wrong, probably the request for avatar family failed
- {
- WORD wError;
- if (wBufferLength >= 2)
- unpackWord(&pBuffer, &wError);
- else
- wError = 0;
-
- LogFamilyError(ICQ_SERVICE_FAMILY, wError);
- }
- break;
-
- // Stuff we don't care about
- case ICQ_SERVER_MOTD:
- debugLogA("Server message of the day");
- break;
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_SERVICE_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-
-char* CIcqProto::buildUinList(int subtype, size_t wMaxLen, MCONTACT *hContactResume)
-{
- MCONTACT hContact;
- WORD wCurrentLen = 0;
- int add;
-
- char *szList = (char*)SAFE_MALLOC(db_get_contact_count() * UINMAXLEN);
-
- char szLen[2];
- szLen[1] = '\0';
-
- if (*hContactResume)
- hContact = *hContactResume;
- else
- hContact = db_find_first(m_szModuleName);
-
- while (hContact != NULL) {
- DWORD dwUIN;
- uid_str szUID;
- if (!getContactUid(hContact, &dwUIN, &szUID)) {
- szLen[0] = (char)mir_strlen(strUID(dwUIN, szUID));
-
- switch (subtype) {
- case BUL_VISIBLE:
- add = ID_STATUS_ONLINE == getWord(hContact, "ApparentMode", 0);
- break;
-
- case BUL_INVISIBLE:
- add = ID_STATUS_OFFLINE == getWord(hContact, "ApparentMode", 0);
- break;
-
- case BUL_TEMPVISIBLE:
- add = getByte(hContact, "TemporaryVisible", 0);
- // clear temporary flag
- // Here we assume that all temporary contacts will be in one packet
- setByte(hContact, "TemporaryVisible", 0);
- break;
-
- default:
- add = 1;
-
- // If we are in SS mode, we only add those contacts that are
- // not in our SS list, or are awaiting authorization, to our
- // client side list
- if (m_bSsiEnabled && getWord(hContact, DBSETTING_SERVLIST_ID, 0) &&
- !getByte(hContact, "Auth", 0))
- add = 0;
-
- // Never add hidden contacts to CS list
- if (db_get_b(hContact, "CList", "Hidden", 0))
- add = 0;
-
- break;
- }
-
- if (add) {
- wCurrentLen += szLen[0] + 1;
- if (wCurrentLen > wMaxLen) {
- *hContactResume = hContact;
- return szList;
- }
-
- mir_strcat(szList, szLen);
- mir_strcat(szList, szUID);
- }
- }
-
- hContact = db_find_next(hContact, m_szModuleName);
- }
- *hContactResume = NULL;
-
- return szList;
-}
-
-void CIcqProto::sendEntireListServ(WORD wFamily, WORD wSubtype, int listType)
-{
- MCONTACT hResumeContact = NULL;
-
- do { // server doesn't seem to be able to cope with packets larger than 8k
- // send only about 100contacts per packet
- char *szList = buildUinList(listType, 0x3E8, &hResumeContact);
-
- size_t nListLen = mir_strlen(szList);
- if (nListLen) {
- icq_packet packet;
- serverPacketInit(&packet, nListLen + 10);
- packFNACHeader(&packet, wFamily, wSubtype);
- packBuffer(&packet, (LPBYTE)szList, nListLen);
- sendServPacket(&packet);
- }
-
- SAFE_FREE((void**)&szList);
- } while (hResumeContact);
-}
-
-
-static void packShortCapability(icq_packet *packet, WORD wCapability)
-{
- // pack standard capability
- DWORD dwQ1 = 0x09460000 | wCapability;
-
- packDWord(packet, dwQ1);
- packDWord(packet, 0x4c7f11d1);
- packDWord(packet, 0x82224445);
- packDWord(packet, 0x53540000);
-}
-
-// CLI_SETUSERINFO
-void CIcqProto::setUserInfo()
-{
- icq_packet packet;
- size_t wAdditionalData = 0;
- BYTE bXStatus = getContactXStatus(NULL);
-
- wAdditionalData += 16; // MTN
- wAdditionalData += 16; // symbol ids
- wAdditionalData += 16; // unicode
- wAdditionalData += 16; // new caps
- wAdditionalData += 16; // xtraz
- wAdditionalData += 16; // oscar file transfers
-
- if (m_bAvatarsEnabled)
- wAdditionalData += 16;
- if (m_bXStatusEnabled && bXStatus != 0)
- wAdditionalData += 16;
- wAdditionalData += 16; // html
- wAdditionalData += 16; // string user id support
-
- wAdditionalData += CustomCapList.getCount() * 16;
-
- //MIM/PackName
- bool bHasPackName = false;
- DBVARIANT dbv;
- if (!db_get_s(0, "ICQCaps", "PackName", &dbv)) {
- //MIM/PackName
- bHasPackName = true;
- wAdditionalData += 16;
- }
-
- serverPacketInit(&packet, 62 + wAdditionalData);
- packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_SET_USER_INFO);
-
- /* TLV(5): capability data */
- packWord(&packet, 0x0005);
- packWord(&packet, WORD(48 + wAdditionalData));
-
- packDWord(&packet, 0x563FC809); // CAP_TYPING
- packDWord(&packet, 0x0B6F41BD);
- packDWord(&packet, 0x9F794226);
- packDWord(&packet, 0x09DFA2F3);
-
- packShortCapability(&packet, 0x1349); // AIM_CAPS_ICQSERVERRELAY
-
- // Broadcasts the capability to receive UTF8 encoded messages
- packShortCapability(&packet, 0x134E); // CAP_UTF8MSGS
-
- // Tells server we understand to new format of caps
- packShortCapability(&packet, 0x0000); // CAP_SHORTCAPS
-
- packDWord(&packet, 0x1a093c6c); // CAP_XTRAZ
- packDWord(&packet, 0xd7fd4ec5); // Broadcasts the capability to handle
- packDWord(&packet, 0x9d51a647); // Xtraz
- packDWord(&packet, 0x4e34f5a0);
-
- if (m_bAvatarsEnabled)
- packShortCapability(&packet, 0x134C); // CAP_DEVILS
-
- // Broadcasts the capability to receive Oscar File Transfers
- packShortCapability(&packet, 0x1343); // CAP_AIM_FILE
-
- // Tells the server we can speak to AIM
- packShortCapability(&packet, 0x134D); // CAP_AIM_COMPATIBLE
- packShortCapability(&packet, 0x134B); // CAP_SENDBUDDYLIST
-
- if (m_bXStatusEnabled && bXStatus != 0)
- packBuffer(&packet, capXStatus[bXStatus - 1], BINARY_CAP_SIZE);
-
- packShortCapability(&packet, 0x1344); // CAP_ICQDIRECT
- packShortCapability(&packet, 0x0002); // CAP_HTMLMSGS
-
- packDWord(&packet, 0x4D697261); // Miranda Signature
- packDWord(&packet, 0x6E64614E);
-
- MFileVersion v;
- Miranda_GetFileVersion(&v);
- packWord(&packet, v[0]);
- packWord(&packet, v[1]);
- packWord(&packet, v[2]);
- packWord(&packet, v[3]);
-
- //MIM/PackName
- if (bHasPackName) {
- packBuffer(&packet, (BYTE*)dbv.pszVal, 0x10);
- db_free(&dbv);
- }
-
- for (auto &it : CustomCapList)
- packBuffer(&packet, (PBYTE)it->caps, 0x10);
-
- sendServPacket(&packet);
-}
-
-
-void CIcqProto::handleServUINSettings(int nPort, serverthread_info *info)
-{
- setUserInfo();
-
- /* SNAC 3,4: Tell server who's on our list (deprecated) */
- /* SNAC 3,15: Try to add unauthorised contacts to temporary list */
- sendEntireListServ(ICQ_BUDDY_FAMILY, ICQ_USER_ADDTOTEMPLIST, BUL_ALLCONTACTS);
-
- if (m_iDesiredStatus == ID_STATUS_INVISIBLE) {
- /* Tell server who's on our visible list (deprecated) */
- if (!m_bSsiEnabled)
- sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDVISIBLE, BUL_VISIBLE);
- else
- updateServVisibilityCode(3);
- }
-
- if (m_iDesiredStatus != ID_STATUS_INVISIBLE) {
- /* Tell server who's on our invisible list (deprecated) */
- if (!m_bSsiEnabled)
- sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDINVISIBLE, BUL_INVISIBLE);
- else
- updateServVisibilityCode(4);
- }
-
- // SNAC 1,1E: Set status
- icq_packet packet;
- {
- DWORD dwDirectCookie = rand() ^ (rand() << 16);
-
- // Get status
- WORD wStatus = MirandaStatusToIcq(m_iDesiredStatus);
-
- // Get status note & mood
- char *szStatusNote = PrepareStatusNote(m_iDesiredStatus);
- BYTE bXStatus = getContactXStatus(NULL);
- char szMoodData[32];
-
- // prepare mood id
- if (m_bMoodsEnabled && bXStatus && moodXStatus[bXStatus - 1] != -1)
- mir_snprintf(szMoodData, "icqmood%d", moodXStatus[bXStatus - 1]);
- else
- szMoodData[0] = '\0';
-
- //! Tricky code, this ensures that the status note will be saved to the directory
- SetStatusNote(szStatusNote, m_bGatewayMode ? 5000 : 2500, TRUE);
-
- size_t wStatusNoteLen = mir_strlen(szStatusNote);
- size_t wStatusMoodLen = mir_strlen(szMoodData);
- size_t wSessionDataLen = (wStatusNoteLen ? wStatusNoteLen + 4 : 0) + 4 + wStatusMoodLen + 4;
-
- serverPacketInit(&packet, 71 + (wSessionDataLen ? wSessionDataLen + 4 : 0));
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS);
- packDWord(&packet, 0x00060004); // TLV 6: Status mode and security flags
- packWord(&packet, GetMyStatusFlags()); // Status flags
- packWord(&packet, wStatus); // Status
- packTLVWord(&packet, 0x0008, 0x0A06); // TLV 8: Independent Status Messages
- packDWord(&packet, 0x000c0025); // TLV C: Direct connection info
- packDWord(&packet, getDword("RealIP", 0));
- packDWord(&packet, nPort);
- packByte(&packet, DC_TYPE); // TCP/FLAG firewall settings
- packWord(&packet, ICQ_VERSION);
- packDWord(&packet, dwDirectCookie); // DC Cookie
- packDWord(&packet, WEBFRONTPORT); // Web front port
- packDWord(&packet, CLIENTFEATURES); // Client features
- packDWord(&packet, 0x7fffffff); // Abused timestamp
- packDWord(&packet, ICQ_PLUG_VERSION); // Abused timestamp
- if (ServiceExists("SecureIM/IsContactSecured"))
- packDWord(&packet, 0x5AFEC0DE); // SecureIM Abuse
- else
- packDWord(&packet, 0x00000000); // Timestamp
- packWord(&packet, 0x0000); // Unknown
- packTLVWord(&packet, 0x001F, 0x0000);
-
- if (wSessionDataLen) { // Pack session data
- packWord(&packet, 0x1D); // TLV 1D
- packWord(&packet, WORD(wSessionDataLen)); // TLV length
- packWord(&packet, 0x02); // Item Type
- if (wStatusNoteLen) {
- packWord(&packet, 0x400 | WORD(wStatusNoteLen + 4)); // Flags + Item Length
- packWord(&packet, WORD(wStatusNoteLen)); // Text Length
- packBuffer(&packet, (LPBYTE)szStatusNote, wStatusNoteLen);
- packWord(&packet, 0); // Encoding not specified (utf-8 is default)
- }
- else
- packWord(&packet, 0); // Flags + Item Length
- packWord(&packet, 0x0E); // Item Type
- packWord(&packet, WORD(wStatusMoodLen)); // Flags + Item Length
- if (wStatusMoodLen)
- packBuffer(&packet, (LPBYTE)szMoodData, wStatusMoodLen); // Mood
-
- // Save current status note & mood
- db_set_utf(NULL, m_szModuleName, DBSETTING_STATUS_NOTE, szStatusNote);
- setString(DBSETTING_STATUS_MOOD, szMoodData);
- }
- // Release memory
- SAFE_FREE(&szStatusNote);
-
- sendServPacket(&packet);
- }
-
- /* SNAC 1,11 */
- serverPacketInit(&packet, 14);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_IDLE);
- packDWord(&packet, 0x00000000);
-
- sendServPacket(&packet);
- m_bIdleMode = false;
-
- // Change status
- SetCurrentStatus(m_iDesiredStatus);
-
- // Finish Login sequence
- serverPacketInit(&packet, 98);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_READY);
- packDWord(&packet, 0x00220001); // imitate ICQ 6 behaviour
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x00010004);
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x00130004);
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x00020001);
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x00030001);
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x00150001);
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x00040001);
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x00060001);
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x00090001);
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x000A0001);
- packDWord(&packet, 0x0110164f);
- packDWord(&packet, 0x000B0001);
- packDWord(&packet, 0x0110164f);
-
- sendServPacket(&packet);
-
- debugLogA(" *** Yeehah, login sequence complete");
-
- // login sequence is complete enter logged-in mode
- info->bLoggedIn = true;
- m_bConnectionLost = false;
-
- // enable auto info-update routine
- icq_EnableUserLookup(true);
-
- if (!info->isMigrating) {
- // Get Offline Messages Reqeust
- cookie_offline_messages *ack = (cookie_offline_messages*)SAFE_MALLOC(sizeof(cookie_offline_messages));
- if (ack) {
- DWORD dwCookie = AllocateCookie(CKT_OFFLINEMESSAGE, ICQ_MSG_CLI_REQ_OFFLINE, 0, ack);
-
- serverPacketInit(&packet, 10);
- packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_CLI_REQ_OFFLINE, 0, dwCookie);
-
- sendServPacket(&packet);
- }
- else icq_LogMessage(LOG_WARNING, LPGEN("Failed to request offline messages. They may be received next time you log in."));
-
- // Update our information from the server
- sendOwnerInfoRequest();
-
- // Request info updates on all contacts
- icq_RescanInfoUpdate();
-
- // Start sending Keep-Alive packets
- StartKeepAlive(info);
-
- if (m_bAvatarsEnabled) { // Send SNAC 1,4 - request avatar family 0x10 connection
- icq_requestnewfamily(ICQ_AVATAR_FAMILY, &CIcqProto::StartAvatarThread);
-
- m_avatarsConnectionPending = TRUE;
- debugLogA("Requesting Avatar family entry point.");
- }
-
- // Set last xstatus
- updateServerCustomStatus(TRUE);
- }
- info->isMigrating = false;
-
- mir_cslock l(m_modeMsgsMutex);
- char **szAwayMsg = MirandaStatusToAwayMsg(m_iStatus);
- if (szAwayMsg)
- icq_sendSetAimAwayMsgServ(*szAwayMsg);
-}
diff --git a/protocols/IcqOscarJ/src/fam_02location.cpp b/protocols/IcqOscarJ/src/fam_02location.cpp
deleted file mode 100644
index d870eed20a..0000000000
--- a/protocols/IcqOscarJ/src/fam_02location.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Handles packets from Location family
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-extern const char* cliSpamBot;
-
-void CIcqProto::handleLocationFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader)
-{
- switch (pSnacHeader->wSubtype) {
- case ICQ_LOCATION_RIGHTS_REPLY: // Reply to CLI_REQLOCATION
- debugLogA("Server sent SNAC(x02,x03) - SRV_LOCATION_RIGHTS_REPLY");
- break;
-
- case ICQ_LOCATION_USR_INFO_REPLY: // AIM user info reply
- handleLocationUserInfoReply(pBuffer, wBufferLength, pSnacHeader->dwRef);
- break;
-
- case ICQ_ERROR:
- {
- WORD wError;
- if (wBufferLength >= 2)
- unpackWord(&pBuffer, &wError);
- else
- wError = 0;
-
- if (wError == 4) {
- MCONTACT hCookieContact;
- cookie_fam15_data *pCookieData;
- if (FindCookie(pSnacHeader->dwRef, &hCookieContact, (void**)&pCookieData) && !getContactUin(hCookieContact) && pCookieData->bRequestType == REQUESTTYPE_PROFILE) {
- ProtoBroadcastAck(hCookieContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0);
- ReleaseCookie(pSnacHeader->dwRef);
- }
- }
-
- LogFamilyError(ICQ_LOCATION_FAMILY, wError);
- break;
- }
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_LOCATION_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-static char* AimApplyEncoding(char* pszStr, const char* pszEncoding)
-{
- // decode encoding to ANSI only
- if (pszStr && pszEncoding) {
- const char *szEnc = strstrnull(pszEncoding, "charset=");
- if (szEnc) { // decode custom encoding to Utf-8
- char *szStr = ApplyEncoding(pszStr, szEnc + 9);
- // decode utf-8 to ansi
- char *szRes = nullptr;
-
- SAFE_FREE((void**)&pszStr);
- if (!utf8_decode(szStr, &szRes))
- szRes = _strdup(szStr); // Legacy fix
- SAFE_FREE((void**)&szStr);
-
- return szRes;
- }
- }
- return pszStr;
-}
-
-void CIcqProto::handleLocationUserInfoReply(BYTE* buf, size_t wLen, DWORD dwCookie)
-{
- DWORD dwUIN;
- uid_str szUID;
- WORD wTLVCount;
- WORD wWarningLevel;
- WORD status;
- cookie_message_data *pCookieData;
-
- // Unpack the sender's user ID
- if (!unpackUID(&buf, &wLen, &dwUIN, &szUID)) return;
-
- // Syntax check
- if (wLen < 4)
- return;
-
- // Warning level?
- unpackWord(&buf, &wWarningLevel);
- wLen -= 2;
-
- // TLV count
- unpackWord(&buf, &wTLVCount);
- wLen -= 2;
-
- // Determine contact
- MCONTACT hContact = HContactFromUID(dwUIN, szUID, nullptr);
-
- // Ignore away status if the user is not already on our list
- if (hContact == INVALID_CONTACT_ID) {
- debugLogA("Ignoring away reply (%s)", strUID(dwUIN, szUID));
- return;
- }
-
- MCONTACT hCookieContact;
- if (!FindCookie(dwCookie, &hCookieContact, (void**)&pCookieData)) {
- debugLogA("Error: Received unexpected away reply from %s", strUID(dwUIN, szUID));
- return;
- }
-
- if (hContact != hCookieContact) {
- debugLogA("Error: Away reply Contact does not match Cookie Contact(0x%x != 0x%x)", hContact, hCookieContact);
-
- ReleaseCookie(dwCookie); // This could be a bad idea, but I think it is safe
- return;
- }
-
- switch (GetCookieType(dwCookie)) {
- case CKT_FAMILYSPECIAL:
- ReleaseCookie(dwCookie);
- {
- // Syntax check
- if (wLen < 4)
- return;
-
- char *szMsg = nullptr;
- BYTE *tmp = buf;
-
- // Get general chain
- oscar_tlv_chain* pChain;
- if (!(pChain = readIntoTLVChain(&buf, wLen, wTLVCount)))
- return;
-
- disposeChain(&pChain);
-
- wLen -= (buf - tmp);
-
- // Get extra chain
- if (pChain = readIntoTLVChain(&buf, wLen, 2)) {
- char *szEncoding = nullptr;
-
- // Get Profile encoding TLV
- oscar_tlv *pTLV = pChain->getTLV(0x05, 1);
- if (pTLV && pTLV->wLen > 0) // store client capabilities
- db_set_blob(hContact, m_szModuleName, "CapBuf", pTLV->pData, pTLV->wLen);
- else
- delSetting(hContact, "CapBuf");
-
- pTLV = pChain->getTLV(0x01, 1);
- if (pTLV && (pTLV->wLen >= 1)) {
- szEncoding = (char*)_alloca(pTLV->wLen + 1);
- memcpy(szEncoding, pTLV->pData, pTLV->wLen);
- szEncoding[pTLV->wLen] = '\0';
- }
- // Get Profile info TLV
- pTLV = pChain->getTLV(0x02, 1);
- if (pTLV && (pTLV->wLen >= 1)) {
- szMsg = (char*)SAFE_MALLOC(pTLV->wLen + 2);
- memcpy(szMsg, pTLV->pData, pTLV->wLen);
- szMsg[pTLV->wLen] = '\0';
- szMsg[pTLV->wLen + 1] = '\0';
- szMsg = AimApplyEncoding(szMsg, szEncoding);
- szMsg = EliminateHtml(szMsg, pTLV->wLen);
- }
- // Free TLV chain
- disposeChain(&pChain);
- }
-
- setString(hContact, "About", szMsg);
- ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)1, 0);
-
- SAFE_FREE((void**)&szMsg);
- }
- break;
-
- default: // away message
- status = AwayMsgTypeToStatus(pCookieData->nAckType);
- if (status == ID_STATUS_OFFLINE) {
- debugLogA("SNAC(2.6) Ignoring unknown status message from %s", strUID(dwUIN, szUID));
-
- ReleaseCookie(dwCookie);
- return;
- }
-
- ReleaseCookie(dwCookie);
-
- // Syntax check
- if (wLen < 4)
- return;
-
- BYTE *tmp = buf;
-
- // Get general chain
- oscar_tlv_chain* pChain;
- if (!(pChain = readIntoTLVChain(&buf, wLen, wTLVCount)))
- return;
-
- disposeChain(&pChain);
-
- wLen -= (buf - tmp);
-
- // Get extra chain
- char *szMsg = nullptr;
- if (pChain = readIntoTLVChain(&buf, wLen, 2)) {
- char *szEncoding = nullptr;
-
- // Get Away encoding TLV
- oscar_tlv *pTLV = pChain->getTLV(0x03, 1);
- if (pTLV && (pTLV->wLen >= 1)) {
- szEncoding = (char*)_alloca(pTLV->wLen + 1);
- memcpy(szEncoding, pTLV->pData, pTLV->wLen);
- szEncoding[pTLV->wLen] = '\0';
- }
- // Get Away info TLV
- pTLV = pChain->getTLV(0x04, 1);
- if (pTLV && (pTLV->wLen >= 1)) {
- szMsg = (char*)SAFE_MALLOC(pTLV->wLen + 2);
- memcpy(szMsg, pTLV->pData, pTLV->wLen);
- szMsg[pTLV->wLen] = '\0';
- szMsg[pTLV->wLen + 1] = '\0';
- szMsg = AimApplyEncoding(szMsg, szEncoding);
- szMsg = EliminateHtml(szMsg, pTLV->wLen);
- }
- // Free TLV chain
- disposeChain(&pChain);
- }
-
- PROTORECVEVENT pre = { 0 };
- pre.szMessage = szMsg ? szMsg : (char *)"";
- pre.timestamp = time(0);
- pre.lParam = dwCookie;
- ProtoChainRecv(hContact, PSR_AWAYMSG, status, (LPARAM)&pre);
-
- SAFE_FREE((void**)&szMsg);
- }
-}
diff --git a/protocols/IcqOscarJ/src/fam_03buddy.cpp b/protocols/IcqOscarJ/src/fam_03buddy.cpp
deleted file mode 100644
index f2d52509fc..0000000000
--- a/protocols/IcqOscarJ/src/fam_03buddy.cpp
+++ /dev/null
@@ -1,716 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Handles packets from Buddy family
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-extern const char* cliSpamBot;
-
-void CIcqProto::handleBuddyFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info)
-{
- switch (pSnacHeader->wSubtype) {
- case ICQ_USER_ONLINE:
- handleUserOnline(pBuffer, wBufferLength, info);
- break;
-
- case ICQ_USER_OFFLINE:
- handleUserOffline(pBuffer, wBufferLength);
- break;
-
- case ICQ_USER_SRV_REPLYBUDDY:
- handleReplyBuddy(pBuffer, wBufferLength);
- break;
-
- case ICQ_USER_NOTIFY_REJECTED:
- handleNotifyRejected(pBuffer, wBufferLength);
- break;
-
- case ICQ_ERROR:
- {
- WORD wError;
-
- if (wBufferLength >= 2)
- unpackWord(&pBuffer, &wError);
- else
- wError = 0;
-
- LogFamilyError(ICQ_BUDDY_FAMILY, wError);
- }
- break;
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_BUDDY_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-void CIcqProto::handleReplyBuddy(BYTE *buf, size_t wPackLen)
-{
- oscar_tlv_chain *pChain = readIntoTLVChain(&buf, wPackLen, 0);
- if (pChain) {
- DWORD wMaxUins = pChain->getWord(1, 1);
- DWORD wMaxWatchers = pChain->getWord(2, 1);
- DWORD wMaxTemporary = pChain->getWord(4, 1);
-
- debugLogA("MaxUINs %u", wMaxUins);
- debugLogA("MaxWatchers %u", wMaxWatchers);
- debugLogA("MaxTemporary %u", wMaxTemporary);
-
- disposeChain(&pChain);
- }
- else debugLogA("Error: Malformed BuddyReply");
-}
-
-int unpackSessionDataItem(oscar_tlv_chain *pChain, WORD wItemType, BYTE **ppItemData, WORD *pwItemSize, BYTE *pbItemFlags)
-{
- int len = 0;
- BYTE *data;
-
- oscar_tlv *tlv = pChain->getTLV(0x1D, 1);
- if (tlv) {
- len = tlv->wLen;
- data = tlv->pData;
- }
-
- while (len >= 4) {
- // parse session data items one by one
- WORD itemType;
- BYTE itemFlags, itemLen;
-
- unpackWord(&data, &itemType);
- unpackByte(&data, &itemFlags);
- unpackByte(&data, &itemLen);
- len -= 4;
-
- // just some validity check
- if (itemLen > len)
- itemLen = len;
-
- if (itemType == wItemType) {
- // found the requested item
- if (ppItemData)
- *ppItemData = data;
- if (pwItemSize)
- *pwItemSize = itemLen;
- if (pbItemFlags)
- *pbItemFlags = itemFlags;
-
- return 1; // Success
- }
- data += itemLen;
- len -= itemLen;
- }
- return 0;
-}
-
-
-// TLV(1) User class
-// TLV(3) Signon time
-// TLV(4) Idle time (in minutes)
-// TLV(5) Member since
-// TLV(6) New status
-// TLV(8) Status Capabilities
-// TLV(A) External IP
-// TLV(C) DC Info
-// TLV(D) Capabilities
-// TLV(F) Session timer (in seconds)
-// TLV(14) Instance number (AIM only)
-// TLV(19) Short capabilities
-// TLV(1D) Session Data (Avatar, Mood, etc.)
-// TLV(1F) User class (upper bytes)
-// TLV(26) AIM Profile update time
-// TLV(27) AIM Away message update time
-// TLV(29) Away status since
-// TLV(2B) URL to protocol icon
-// TLV(2F) unknown key
-// TLV(30) unknown timestamp
-
-void CIcqProto::handleUserOnline(BYTE *buf, size_t wLen, serverthread_info*)
-{
- DWORD dwPort = 0;
- DWORD dwRealIP = 0;
- DWORD dwUIN;
- uid_str szUID;
- DWORD dwDirectConnCookie = 0;
- DWORD dwWebPort = 0;
- DWORD dwFT1 = 0, dwFT2 = 0, dwFT3 = 0;
- const char *szClient = nullptr;
- BYTE bClientId = 0;
- WORD wVersion = 0;
- WORD wTLVCount;
- WORD wWarningLevel;
- WORD wStatusFlags;
- WORD wStatus = 0, wOldStatus = 0;
- BYTE nTCPFlag = 0;
- char szStrBuf[MAX_PATH];
-
- // Unpack the sender's user ID
- if (!unpackUID(&buf, &wLen, &dwUIN, &szUID))
- return;
-
- // Syntax check
- if (wLen < 4)
- return;
-
- // Warning level?
- unpackWord(&buf, &wWarningLevel);
- wLen -= 2;
-
- // TLV count
- unpackWord(&buf, &wTLVCount);
- wLen -= 2;
-
- // Ignore status notification if the user is not already on our list
- MCONTACT hContact = HContactFromUID(dwUIN, szUID, nullptr);
- if (hContact == INVALID_CONTACT_ID) {
- debugLogA("Ignoring user online (%s)", strUID(dwUIN, szUID));
- return;
- }
-
- // Read user info TLVs
- oscar_tlv_chain *pChain;
- oscar_tlv *pTLV;
-
- // Syntax check
- if (wLen < 4)
- return;
-
- // Get chain
- if (!(pChain = readIntoTLVChain(&buf, wLen, wTLVCount)))
- return;
-
- // Get Class word
- WORD wClass = pChain->getWord(0x01, 1);
- int nIsICQ = wClass & CLASS_ICQ;
-
- if (dwUIN) {
- // Get DC info TLV
- pTLV = pChain->getTLV(0x0C, 1);
- if (pTLV && (pTLV->wLen >= 15)) {
- BYTE *pBuffer = pTLV->pData;
-
- nIsICQ = TRUE;
-
- unpackDWord(&pBuffer, &dwRealIP);
- unpackDWord(&pBuffer, &dwPort);
- unpackByte(&pBuffer, &nTCPFlag);
- unpackWord(&pBuffer, &wVersion);
- unpackDWord(&pBuffer, &dwDirectConnCookie);
- unpackDWord(&pBuffer, &dwWebPort); // Web front port
- pBuffer += 4; // Client features
-
- // Get faked time signatures, used to identify clients
- if (pTLV->wLen >= 0x23) {
- unpackDWord(&pBuffer, &dwFT1);
- unpackDWord(&pBuffer, &dwFT2);
- unpackDWord(&pBuffer, &dwFT3);
- }
- }
-
- // Get Status info TLV
- pTLV = pChain->getTLV(0x06, 1);
- if (pTLV && (pTLV->wLen >= 4)) {
- BYTE *pBuffer = pTLV->pData;
- unpackWord(&pBuffer, &wStatusFlags);
- unpackWord(&pBuffer, &wStatus);
- }
- else if (!nIsICQ) {
- // Connected thru AIM client, guess by user class
- if (wClass & CLASS_AWAY)
- wStatus = ID_STATUS_AWAY;
- else if (wClass & CLASS_WIRELESS)
- wStatus = ID_STATUS_ONTHEPHONE;
- else
- wStatus = ID_STATUS_ONLINE;
-
- wStatusFlags = 0;
- }
- else {
- // Huh? No status TLV? Lets guess then...
- wStatusFlags = 0;
- wStatus = ICQ_STATUS_ONLINE;
- }
- }
- else {
- nIsICQ = FALSE;
-
- if (wClass & CLASS_AWAY)
- wStatus = ID_STATUS_AWAY;
- else if (wClass & CLASS_WIRELESS)
- wStatus = ID_STATUS_ONTHEPHONE;
- else
- wStatus = ID_STATUS_ONLINE;
-
- wStatusFlags = 0;
- }
-
- debugLogA("Flags are %x", wStatusFlags);
- debugLogA("Status is %x", wStatus);
-
- // Get IP TLV
- DWORD dwIP = pChain->getDWord(0x0A, 1);
-
- // Get Online Since TLV
- DWORD dwOnlineSince = pChain->getDWord(0x03, 1);
-
- // Get Away Since TLV
- DWORD dwAwaySince = pChain->getDWord(0x29, 1);
-
- // Get Member Since TLV
- DWORD dwMemberSince = pChain->getDWord(0x05, 1);
-
- // Get Idle timer TLV
- WORD wIdleTimer = pChain->getWord(0x04, 1);
- time_t tIdleTS = 0;
- if (wIdleTimer) {
- time(&tIdleTS);
- tIdleTS -= (wIdleTimer * 60);
- }
-
- if (wIdleTimer)
- debugLogA("Idle timer is %u.", wIdleTimer);
- debugLogA("Online since %s", time2text(dwOnlineSince));
- if (dwAwaySince)
- debugLogA("Status was set on %s", time2text(dwAwaySince));
-
- // Check client capabilities
- if (hContact != NULL) {
- wOldStatus = getContactStatus(hContact);
-
- // Collect all Capability info from TLV chain
- BYTE *capBuf = nullptr;
- WORD capLen = 0;
-
- // Get Location Capability Info TLVs
- oscar_tlv *pFullTLV = pChain->getTLV(0x0D, 1);
- oscar_tlv *pShortTLV = pChain->getTLV(0x19, 1);
-
- if (pFullTLV && (pFullTLV->wLen >= BINARY_CAP_SIZE))
- capLen += pFullTLV->wLen;
-
- if (pShortTLV && (pShortTLV->wLen >= 2))
- capLen += (pShortTLV->wLen * 8);
-
- capBuf = (BYTE*)_alloca(capLen + BINARY_CAP_SIZE);
-
- if (capLen) {
- BYTE *pCapability = capBuf;
-
- capLen = 0; // we need to recount that
-
- if (pFullTLV && (pFullTLV->wLen >= BINARY_CAP_SIZE)) {
- // copy classic Capabilities
- BYTE *cData = pFullTLV->pData;
- int cLen = pFullTLV->wLen;
-
- while (cLen) {
- // be impervious to duplicates (AOL sends them sometimes)
- if (!capLen || !MatchCapability(capBuf, capLen, (capstr*)cData, BINARY_CAP_SIZE)) {
- // not present, add
- memcpy(pCapability, cData, BINARY_CAP_SIZE);
- capLen += BINARY_CAP_SIZE;
- pCapability += BINARY_CAP_SIZE;
- }
- cData += BINARY_CAP_SIZE;
- cLen -= BINARY_CAP_SIZE;
- }
- }
-
- if (pShortTLV && (pShortTLV->wLen >= 2)) {
- // copy short Capabilities
- capstr tmp;
- BYTE *cData = pShortTLV->pData;
- int cLen = pShortTLV->wLen;
-
- memcpy(tmp, capShortCaps, BINARY_CAP_SIZE);
- while (cLen) {
- // be impervious to duplicates (AOL sends them sometimes)
- tmp[2] = cData[0];
- tmp[3] = cData[1];
-
- if (!capLen || !MatchCapability(capBuf, capLen, &tmp, BINARY_CAP_SIZE)) {
- // not present, add
- memcpy(pCapability, tmp, BINARY_CAP_SIZE);
- capLen += BINARY_CAP_SIZE;
- pCapability += BINARY_CAP_SIZE;
- }
- cData += 2;
- cLen -= 2;
- }
- }
- debugLogA("Detected %d capability items.", capLen / BINARY_CAP_SIZE);
- }
-
- if (capLen) {
-#ifdef _DEBUG
- for (WORD i = 0; i < capLen; i += BINARY_CAP_SIZE) {
- char tmp[100];
- bin2hex(capBuf + i, BINARY_CAP_SIZE, tmp);
- debugLogA("Capability: %s", tmp);
- }
-#endif
-
- // Update the contact's capabilies if present in packet
- SetCapabilitiesFromBuffer(hContact, capBuf, capLen, wOldStatus == ID_STATUS_OFFLINE);
-
- char *szCurrentClient = wOldStatus == ID_STATUS_OFFLINE ? nullptr : getSettingStringUtf(hContact, "MirVer", nullptr);
-
- szClient = detectUserClient(hContact, nIsICQ, wClass, dwOnlineSince, szCurrentClient, wVersion, dwFT1, dwFT2, dwFT3, dwDirectConnCookie, dwWebPort, capBuf, capLen, &bClientId, szStrBuf);
- // Check if the client changed, if not do not change
- if (szCurrentClient && !mir_strcmp(szCurrentClient, szClient))
- szClient = (const char*)-1;
- SAFE_FREE(&szCurrentClient);
- }
- else if (wOldStatus == ID_STATUS_OFFLINE) {
- // Remove the contact's capabilities if coming from offline
- ClearAllContactCapabilities(hContact);
-
- // no capability
- debugLogA("No capability info TLVs");
-
- szClient = detectUserClient(hContact, nIsICQ, wClass, dwOnlineSince, nullptr, wVersion, dwFT1, dwFT2, dwFT3, dwDirectConnCookie, dwWebPort, nullptr, capLen, &bClientId, szStrBuf);
- }
- else // Capabilities not present in update packet, do not touch
- szClient = (const char*)-1; // we don't want to client be overwritten
-
- // handle Xtraz status
- char *moodData = nullptr;
- WORD moodSize = 0;
-
- unpackSessionDataItem(pChain, 0x0E, (BYTE**)&moodData, &moodSize, nullptr);
- if (capLen || wOldStatus == ID_STATUS_OFFLINE)
- handleXStatusCaps(dwUIN, szUID, hContact, capBuf, capLen, moodData, moodSize);
- else
- handleXStatusCaps(dwUIN, szUID, hContact, nullptr, 0, moodData, moodSize);
-
- // Determine support for extended status messages
- if (pChain->getWord(0x08, 1) == 0x0A06)
- SetContactCapabilities(hContact, CAPF_STATUS_MESSAGES);
- else if (wOldStatus == ID_STATUS_OFFLINE)
- ClearContactCapabilities(hContact, CAPF_STATUS_MESSAGES);
-
- if (wOldStatus == ID_STATUS_OFFLINE) {
- if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY))
- debugLogA("Supports advanced messages");
- else
- debugLogA("Does NOT support advanced messages");
- }
-
- if (!nIsICQ) {
- // AIM clients does not advertise these, but do support them
- SetContactCapabilities(hContact, CAPF_UTF | CAPF_TYPING);
- // Server relayed messages are only supported by ICQ clients
- ClearContactCapabilities(hContact, CAPF_SRV_RELAY);
-
- if (dwUIN && wOldStatus == ID_STATUS_OFFLINE)
- debugLogA("Logged in with AIM client");
- }
-
- if (nIsICQ && wVersion < 8) {
- ClearContactCapabilities(hContact, CAPF_SRV_RELAY);
- if (wOldStatus == ID_STATUS_OFFLINE)
- debugLogA("Forcing simple messages due to compability issues");
- }
-
- // Process Avatar Hash
- pTLV = pChain->getTLV(0x1D, 1);
- if (pTLV)
- handleAvatarContactHash(dwUIN, szUID, hContact, pTLV->pData, pTLV->wLen);
- else
- handleAvatarContactHash(dwUIN, szUID, hContact, nullptr, 0);
-
- // Process Status Note
- parseStatusNote(dwUIN, szUID, hContact, pChain);
- }
- // Free TLV chain
- disposeChain(&pChain);
-
- // Save contacts details in database
- if (hContact != NULL) {
- setDword(hContact, "LogonTS", dwOnlineSince);
- setDword(hContact, "AwayTS", dwAwaySince);
- setDword(hContact, "IdleTS", tIdleTS);
-
- if (dwMemberSince)
- setDword(hContact, "MemberTS", dwMemberSince);
-
- if (nIsICQ) {
- // on AIM these are not used
- setDword(hContact, "DirectCookie", dwDirectConnCookie);
- setByte(hContact, "DCType", (BYTE)nTCPFlag);
- setWord(hContact, "UserPort", (WORD)(dwPort & 0xffff));
- setWord(hContact, "Version", wVersion);
- }
- else {
- delSetting(hContact, "DirectCookie");
- delSetting(hContact, "DCType");
- delSetting(hContact, "UserPort");
- delSetting(hContact, "Version");
- }
-
- // if no detection, set uknown
- if (!szClient)
- szClient = (nIsICQ ? "Unknown" : "Unknown AIM");
-
- if (szClient != (char*)-1) {
- db_set_utf(hContact, m_szModuleName, "MirVer", szClient);
- setByte(hContact, "ClientID", bClientId);
- }
-
- if (wOldStatus == ID_STATUS_OFFLINE) {
- setDword(hContact, "IP", dwIP);
- setDword(hContact, "RealIP", dwRealIP);
- }
- else {
- // if not first notification only write significant information
- if (dwIP)
- setDword(hContact, "IP", dwIP);
- if (dwRealIP)
- setDword(hContact, "RealIP", dwRealIP);
- }
- setWord(hContact, "Status", (WORD)IcqStatusToMiranda(wStatus));
-
- // Update info?
- if (dwUIN) {
- // check if the local copy of user details is up-to-date
- if (IsMetaInfoChanged(hContact))
- icq_QueueUser(hContact);
- }
- }
-
- LPCTSTR ptszStatus = Clist_GetStatusModeDescription(IcqStatusToMiranda(wStatus), 0);
- if (wOldStatus != IcqStatusToMiranda(wStatus)) {
- // And a small log notice... if status was changed
- if (nIsICQ)
- debugLogA("%u changed status to %S (v%d).", dwUIN, ptszStatus, wVersion);
- else
- debugLogA("%s changed status to %S.", strUID(dwUIN, szUID), ptszStatus);
- }
-
- if (szClient == cliSpamBot) {
- if (getByte("KillSpambots", DEFAULT_KILLSPAM_ENABLED) && db_get_b(hContact, "CList", "NotOnList", 0)) {
- // kill spammer
- icq_DequeueUser(dwUIN);
- icq_sendRemoveContact(dwUIN, nullptr);
- AddToSpammerList(dwUIN);
- if (getByte("PopupsSpamEnabled", DEFAULT_SPAM_POPUPS_ENABLED))
- ShowPopupMsg(hContact, LPGEN("Spambot Detected"), LPGEN("Contact deleted & further events blocked."), POPTYPE_SPAM);
- db_delete_contact(hContact);
-
- debugLogA("Contact %u deleted", dwUIN);
- }
- }
-}
-
-void CIcqProto::handleUserOffline(BYTE *buf, size_t wLen)
-{
- DWORD dwUIN;
- uid_str szUID;
-
- do {
- oscar_tlv_chain *pChain = nullptr;
- // Unpack the sender's user ID
- if (!unpackUID(&buf, &wLen, &dwUIN, &szUID)) return;
-
- // Warning level?
- buf += 2;
-
- // TLV Count
- WORD wTLVCount;
- unpackWord(&buf, &wTLVCount);
- wLen -= 4;
-
- // Skip the TLV chain
- DWORD dwAwaySince = 0;
- while (wTLVCount && wLen >= 4) {
- WORD wTLVType;
- WORD wTLVLen;
-
- unpackWord(&buf, &wTLVType);
- unpackWord(&buf, &wTLVLen);
- wLen -= 4;
-
- // stop parsing overflowed packet
- if (wTLVLen > wLen) {
- disposeChain(&pChain);
- return;
- }
-
- if (wTLVType == 0x1D) {
- // read only TLV with Session data into chain
- BYTE *pTLV = buf - 4;
- disposeChain(&pChain);
- pChain = readIntoTLVChain(&pTLV, wLen + 4, 1);
- }
- else if (wTLVType == 0x29 && wTLVLen == sizeof(DWORD)) {
- // get Away Since value
- BYTE *pData = buf;
- unpackDWord(&pData, &dwAwaySince);
- }
-
- buf += wTLVLen;
- wLen -= wTLVLen;
- wTLVCount--;
- }
-
- // Determine contact
- MCONTACT hContact = HContactFromUID(dwUIN, szUID, nullptr);
-
- // Skip contacts that are not already on our list or are already offline
- if (hContact != INVALID_CONTACT_ID) {
- WORD wOldStatus = getContactStatus(hContact);
-
- // Process Avatar Hash
- oscar_tlv *pAvatarTLV = pChain ? pChain->getTLV(0x1D, 1) : nullptr;
- if (pAvatarTLV)
- handleAvatarContactHash(dwUIN, szUID, hContact, pAvatarTLV->pData, pAvatarTLV->wLen);
- else
- handleAvatarContactHash(dwUIN, szUID, hContact, nullptr, 0);
-
- // Process Status Note (offline status note)
- parseStatusNote(dwUIN, szUID, hContact, pChain);
-
- // Update status times
- setDword(hContact, "IdleTS", 0);
- setDword(hContact, "AwayTS", dwAwaySince);
-
- // Clear custom status & mood
- char tmp = NULL;
- handleXStatusCaps(dwUIN, szUID, hContact, (BYTE*)&tmp, 0, &tmp, 0);
-
- if (wOldStatus != ID_STATUS_OFFLINE) {
- debugLogA("%s went offline.", strUID(dwUIN, szUID));
-
- setWord(hContact, "Status", ID_STATUS_OFFLINE);
- // close Direct Connections to that user
- CloseContactDirectConns(hContact);
- // Reset DC status
- setByte(hContact, "DCStatus", 0);
- }
- else debugLogA("%s is offline.", strUID(dwUIN, szUID));
- }
-
- // Release memory
- disposeChain(&pChain);
- } while (wLen >= 1);
-}
-
-
-void CIcqProto::parseStatusNote(DWORD dwUin, char *szUid, MCONTACT hContact, oscar_tlv_chain *pChain)
-{
- DWORD dwStatusNoteTS = time(0);
- BYTE *pStatusNoteTS, *pStatusNote;
- WORD wStatusNoteTSLen, wStatusNoteLen;
- BYTE bStatusNoteFlags;
-
- if (unpackSessionDataItem(pChain, 0x0D, &pStatusNoteTS, &wStatusNoteTSLen, nullptr) && wStatusNoteTSLen == sizeof(DWORD))
- unpackDWord(&pStatusNoteTS, &dwStatusNoteTS);
-
- // Get Status Note session item
- if (unpackSessionDataItem(pChain, 0x02, &pStatusNote, &wStatusNoteLen, &bStatusNoteFlags)) {
- char *szStatusNote = nullptr;
-
- if ((bStatusNoteFlags & 4) == 4 && wStatusNoteLen >= 4) {
- BYTE *buf = pStatusNote;
- WORD buflen = wStatusNoteLen - 2;
- WORD wTextLen;
-
- unpackWord(&buf, &wTextLen);
- if (wTextLen > buflen)
- wTextLen = buflen;
-
- if (wTextLen > 0) {
- szStatusNote = (char*)_alloca(wStatusNoteLen + 1);
- unpackString(&buf, szStatusNote, wTextLen);
- szStatusNote[wTextLen] = '\0';
- buflen -= wTextLen;
-
- WORD wEncodingType = 0;
- char *szEncoding = nullptr;
-
- if (buflen >= 2)
- unpackWord(&buf, &wEncodingType);
-
- if (wEncodingType == 1 && buflen > 6) {
- // Encoding specified
- buf += 2;
- buflen -= 2;
- unpackWord(&buf, &wTextLen);
- if (wTextLen > buflen)
- wTextLen = buflen;
- szEncoding = (char*)_alloca(wTextLen + 1);
- unpackString(&buf, szEncoding, wTextLen);
- szEncoding[wTextLen] = '\0';
- }
- else if (UTF8_IsValid(szStatusNote))
- szEncoding = "utf-8";
-
- szStatusNote = ApplyEncoding(szStatusNote, szEncoding);
- }
- }
- // Check if the status note was changed
- if (dwStatusNoteTS > getDword(hContact, DBSETTING_STATUS_NOTE_TIME, 0)) {
- DBVARIANT dbv = { DBVT_DELETED };
-
- if (mir_strlen(szStatusNote) || (!getString(hContact, DBSETTING_STATUS_NOTE, &dbv) && (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) && mir_strlen(dbv.pszVal)))
- debugLogA("%s changed status note to \"%s\"", strUID(dwUin, szUid), szStatusNote ? szStatusNote : "");
-
- db_free(&dbv);
-
- if (szStatusNote)
- db_set_utf(hContact, m_szModuleName, DBSETTING_STATUS_NOTE, szStatusNote);
- else
- delSetting(hContact, DBSETTING_STATUS_NOTE);
- setDword(hContact, DBSETTING_STATUS_NOTE_TIME, dwStatusNoteTS);
-
- if (getContactXStatus(hContact) != 0 || !CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES)) {
- setStatusMsgVar(hContact, szStatusNote, false);
-
- wchar_t *tszNote = mir_utf8decodeW(szStatusNote);
- ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, nullptr, (LPARAM)tszNote);
- mir_free(tszNote);
- }
- }
- SAFE_FREE(&szStatusNote);
- }
- else if (getContactStatus(hContact) == ID_STATUS_OFFLINE) {
- setStatusMsgVar(hContact, nullptr, false);
- delSetting(hContact, DBSETTING_STATUS_NOTE);
- setDword(hContact, DBSETTING_STATUS_NOTE_TIME, dwStatusNoteTS);
- }
-}
-
-void CIcqProto::handleNotifyRejected(BYTE *buf, size_t wPackLen)
-{
- DWORD dwUIN;
- uid_str szUID;
-
- while (wPackLen)
- if (unpackUID(&buf, &wPackLen, &dwUIN, &szUID))
- debugLogA("%s status notification rejected.", strUID(dwUIN, szUID));
-}
diff --git a/protocols/IcqOscarJ/src/fam_04message.cpp b/protocols/IcqOscarJ/src/fam_04message.cpp
deleted file mode 100644
index d3de9c94ce..0000000000
--- a/protocols/IcqOscarJ/src/fam_04message.cpp
+++ /dev/null
@@ -1,2620 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Handles packets from Family 4 ICBM Messages
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleMsgFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader)
-{
- switch (pSnacHeader->wSubtype) {
- case ICQ_MSG_SRV_ERROR: // SNAC(4, 0x01)
- handleRecvServMsgError(pBuffer, wBufferLength, pSnacHeader->dwRef);
- break;
-
- case ICQ_MSG_SRV_REPLYICBM: // SNAC(4, 0x05) SRV_REPLYICBM
- handleReplyICBM();
- break;
-
- case ICQ_MSG_SRV_RECV: // SNAC(4, 0x07)
- handleRecvServMsg(pBuffer, wBufferLength, pSnacHeader->dwRef);
- break;
-
- case ICQ_MSG_SRV_MISSED_MESSAGE: // SNAC(4, 0x0A)
- handleMissedMsg(pBuffer, wBufferLength);
- break;
-
- case ICQ_MSG_RESPONSE: // SNAC(4, 0x0B)
- handleRecvMsgResponse(pBuffer, wBufferLength);
- break;
-
- case ICQ_MSG_SRV_ACK: // SNAC(4, 0x0C) Server acknowledgements
- handleServerAck(pBuffer, wBufferLength, pSnacHeader->dwRef);
- break;
-
- case ICQ_MSG_MTN: // SNAC(4, 0x14) Typing notifications
- handleTypingNotification(pBuffer, wBufferLength);
- break;
-
- case ICQ_MSG_SRV_OFFLINE_REPLY: // SNAC(4, 0x17) Offline Messages response
- handleOffineMessagesReply(pSnacHeader->dwRef);
- break;
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_MSG_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-static void setMsgChannelParams(CIcqProto *ppro, WORD wChan, DWORD dwFlags)
-{
- icq_packet packet;
-
- // Set message parameters for channel wChan (CLI_SET_ICBM_PARAMS)
- serverPacketInit(&packet, 26);
- packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_CLI_SETPARAMS);
- packWord(&packet, wChan); // Channel
- packDWord(&packet, dwFlags); // Flags
- packWord(&packet, MAX_MESSAGESNACSIZE); // Max message snac size
- packWord(&packet, 0x03E7); // Max sender warning level
- packWord(&packet, 0x03E7); // Max receiver warning level
- packWord(&packet, CLIENTRATELIMIT); // Minimum message interval in seconds
- packWord(&packet, 0x0000); // Unknown
- ppro->sendServPacket(&packet);
-}
-
-void CIcqProto::handleReplyICBM()
-{
- // Set message parameters for all channels (imitate ICQ 6)
- setMsgChannelParams(this, 0x0000, 0x0000070B);
-}
-
-void CIcqProto::handleRecvServMsg(BYTE *buf, size_t wLen, DWORD dwRef)
-{
- DWORD dwUin;
- DWORD dwMsgID1;
- DWORD dwMsgID2;
- WORD wTLVCount;
- WORD wMessageFormat;
- uid_str szUID;
-
- if (wLen < 11) { // just do some basic packet checking
- debugLogA("Error: Malformed message thru server");
- return;
- }
-
- // These two values are some kind of reference, we need to save
- // them to send file request responses for example
- unpackLEDWord(&buf, &dwMsgID1); // TODO: msg cookies should be main
- wLen -= 4;
- unpackLEDWord(&buf, &dwMsgID2);
- wLen -= 4;
-
- // The message type used:
- unpackWord(&buf, &wMessageFormat); // 0x0001: Simple message format
- wLen -= 2; // 0x0002: Advanced message format
- // 0x0004: 'New' message format
- // Sender UIN
- if (!unpackUID(&buf, &wLen, &dwUin, &szUID)) return;
-
- if (dwUin && IsOnSpammerList(dwUin)) {
- debugLogA("Ignored Message from known Spammer");
- return;
- }
-
- if (wLen < 4) { // just do some basic packet checking
- debugLogA("Error: Malformed message thru server");
- return;
- }
-
- // Warning level?
- buf += 2;
- wLen -= 2;
-
- // Number of following TLVs, until msg-format dependant TLVs
- unpackWord(&buf, &wTLVCount);
- wLen -= 2;
- if (wTLVCount > 0) {
- // Save current buffer pointer so we can calculate
- // how much data we have left after the chain read.
- BYTE *pBufStart = buf;
- oscar_tlv_chain *chain = readIntoTLVChain(&buf, wLen, wTLVCount);
-
- // This chain contains info that is filled in by the server.
- // TLV(1): unknown
- // TLV(2): date: on since
- // TLV(3): date: on since
- // TLV(4): unknown, usually 0000. Not in file-req or auto-msg-req
- // TLV(6): sender's status
- // TLV(F): a time in seconds, unknown
-
- disposeChain(&chain);
-
- // Update wLen
- wLen -= buf - pBufStart;
- }
-
-
- // This is where the format specific data begins
-
- switch (wMessageFormat) {
-
- case 1: // Simple message format
- handleRecvServMsgType1(buf, wLen, dwUin, szUID, dwMsgID1, dwRef);
- break;
-
- case 2: // Encapsulated messages
- handleRecvServMsgType2(buf, wLen, dwUin, szUID, dwMsgID1, dwMsgID2);
- break;
-
- case 4: // Typed messages
- handleRecvServMsgType4(buf, wLen, dwUin, szUID, dwMsgID1, dwMsgID2, dwRef);
- break;
-
- default:
- debugLogA("Unknown format message thru server - Ref %u, Type: %u, UID: %s", dwRef, wMessageFormat, strUID(dwUin, szUID));
- break;
- }
-}
-
-char* CIcqProto::convertMsgToUserSpecificUtf(MCONTACT hContact, const char *szMsg)
-{
- WORD wCP = getWord(hContact, "CodePage", m_wAnsiCodepage);
- char *usMsg = nullptr;
-
- if (wCP != CP_ACP)
- usMsg = ansi_to_utf8_codepage(szMsg, wCP);
-
- return usMsg;
-}
-
-void CIcqProto::handleRecvServMsgType1(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwRef)
-{
- WORD wTLVType;
- size_t wTLVLen;
- BYTE* pMsgTLV;
-
- if (wLen < 4) { // just perform basic structure check
- debugLogA("Message (format %u) - Ignoring empty message", 1);
- return;
- }
-
- // Unpack the first TLV(2)
- unpackTypedTLV(buf, wLen, 2, &wTLVType, &wTLVLen, &pMsgTLV);
- debugLogA("Message (format %u) - UID: %s", 1, strUID(dwUin, szUID));
-
- // It must be TLV(2)
- if (wTLVType == 2) {
- BYTE *pDataBuf = pMsgTLV;
- oscar_tlv_chain *pChain = readIntoTLVChain(&pDataBuf, wTLVLen, 0);
-
- // TLV(2) contains yet another TLV chain with the following TLVs:
- // TLV(1281): Capability
- // TLV(257): This TLV contains the actual message (can be fragmented)
-
- if (pChain) {
- // Find the capability TLV
- oscar_tlv *pCapabilityTLV = pChain->getTLV(0x0501, 1);
- if (pCapabilityTLV && (pCapabilityTLV->wLen > 0)) {
- WORD wDataLen = pCapabilityTLV->wLen;
- if (wDataLen > 0)
- debugLogA("Message (format 1) - Message has %d caps.", wDataLen);
- }
- else debugLogA("Message (format 1) - No message cap.");
-
- {
- // Parse the message parts, usually only one 0x0101 TLV containing the message,
- // but in some cases there can be more 0x0101 TLVs containing message parts in
- // different encodings (just like the new format of Offline Messages).
- DWORD dwRecvTime;
- char* szMsg = nullptr;
- bool bUtf8 = false;
- PROTORECVEVENT pre = { 0 };
-
- int bAdded;
- MCONTACT hContact = HContactFromUID(dwUin, szUID, &bAdded);
-
- WORD wMsgPart = 1;
- while (oscar_tlv *pMessageTLV = pChain->getTLV(0x0101, wMsgPart)) { // Loop thru all message parts
- if (pMessageTLV->wLen > 4) {
- char *szMsgPart = nullptr;
- bool bMsgPartUnicode = false;
-
- // The message begins with a encoding specification
- // The first WORD is believed to have the following meaning:
- // 0x00: US-ASCII
- // 0x02: Unicode UCS-2 Big Endian encoding
- // 0x03: local 8bit encoding
- BYTE *pMsgBuf = pMessageTLV->pData;
- WORD wEncoding, wCodePage;
- unpackWord(&pMsgBuf, &wEncoding);
- unpackWord(&pMsgBuf, &wCodePage);
-
- WORD wMsgLen = pMessageTLV->wLen - 4;
- debugLogA("Message (format 1) - Part %d: Encoding is 0x%X, page is 0x%X", wMsgPart, wEncoding, wCodePage);
-
- switch (wEncoding) {
- case 2: // UCS-2
- {
- WCHAR *usMsgPart = (WCHAR*)SAFE_MALLOC(wMsgLen + 2);
-
- unpackWideString(&pMsgBuf, usMsgPart, wMsgLen);
- usMsgPart[wMsgLen / sizeof(WCHAR)] = 0;
-
- szMsgPart = make_utf8_string(usMsgPart);
- if (!IsUSASCII(szMsgPart, mir_strlen(szMsgPart)))
- bMsgPartUnicode = true;
- SAFE_FREE(&usMsgPart);
- }
- break;
-
- case 0: // us-ascii
- case 3: // ANSI
- default:
- // Copy the message text into a new proper string.
- szMsgPart = (char*)SAFE_MALLOC(wMsgLen + 1);
- memcpy(szMsgPart, pMsgBuf, wMsgLen);
- szMsgPart[wMsgLen] = '\0';
- break;
- }
-
- // Check if the new part is compatible with the message
- if (!bUtf8 && bMsgPartUnicode) { // make the resulting message utf-8 encoded - need to append utf-8 encoded part
- if (szMsg) { // not necessary to convert - appending first part, only set flags
- char *szUtfMsg = ansi_to_utf8_codepage(szMsg, getWord(hContact, "CodePage", m_wAnsiCodepage));
-
- SAFE_FREE(&szMsg);
- szMsg = szUtfMsg;
- }
- bUtf8 = true;
- }
- if (!bMsgPartUnicode && bUtf8) { // convert message part to utf-8 and append
- char *szUtfPart = ansi_to_utf8_codepage((char*)szMsgPart, getWord(hContact, "CodePage", m_wAnsiCodepage));
- SAFE_FREE(&szMsgPart);
- szMsgPart = szUtfPart;
- }
- // Append the new message part
- szMsg = (char*)SAFE_REALLOC(szMsg, mir_strlen(szMsg) + mir_strlen(szMsgPart) + 1);
-
- mir_strcat(szMsg, szMsgPart);
- SAFE_FREE(&szMsgPart);
- }
- wMsgPart++;
- }
- if (mir_strlen(szMsg)) {
- if (_strnicmp(szMsg, "<html>", 6) == 0) // strip HTML formating from AIM message
- szMsg = EliminateHtml(szMsg, mir_strlen(szMsg));
-
- if (!bUtf8 && !IsUSASCII(szMsg, mir_strlen(szMsg))) { // message is Ansi and contains national characters, create Unicode part by codepage
- char *usMsg = convertMsgToUserSpecificUtf(hContact, szMsg);
- if (usMsg) {
- SAFE_FREE(&szMsg);
- szMsg = usMsg;
- bUtf8 = true;
- }
- }
-
- dwRecvTime = (DWORD)time(0);
-
- { // Check if the message was received as offline
- cookie_offline_messages *cookie;
- if (!(dwRef & 0x80000000) && FindCookie(dwRef, nullptr, (void**)&cookie)) {
- cookie->nMessages++;
-
- WORD wTimeTLVType;
- size_t wTimeTLVLen;
- BYTE *pTimeTLV;
- unpackTypedTLV(buf, wLen, 0x16, &wTimeTLVType, &wTimeTLVLen, &pTimeTLV);
- if (pTimeTLV && wTimeTLVType == 0x16 && wTimeTLVLen == 4) { // found Offline timestamp
- BYTE *pBuf = pTimeTLV;
-
- unpackDWord(&pBuf, &dwRecvTime);
- debugLogA("Message (format %u) - Offline timestamp is %s", 1, time2text(dwRecvTime));
- }
- SAFE_FREE((void**)&pTimeTLV);
- }
- }
- // Create and send the message event
- pre.timestamp = dwRecvTime;
- pre.szMessage = (char *)szMsg;
- ProtoChainRecvMsg(hContact, &pre);
-
- debugLogA("Message (format 1) received");
-
- // Save tick value
- setDword(hContact, "TickTS", time(0) - (dwMsgID1 / 1000));
- }
- else debugLogA("Message (format %u) - Ignoring empty message", 1);
-
- SAFE_FREE(&szMsg);
- }
-
- // Free the chain memory
- disposeChain(&pChain);
- }
- else debugLogA("Failed to read TLV chain in message (format 1)");
- }
- else debugLogA("Unsupported TLV (%u) in message (format %u)", wTLVType, 1);
-
- SAFE_FREE((void**)&pMsgTLV);
-}
-
-void CIcqProto::handleRecvServMsgType2(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2)
-{
- WORD wTLVType;
- size_t wTLVLen;
- BYTE *pDataBuf = nullptr;
-
- if (wLen < 4) {
- debugLogA("Message (format %u) - Ignoring empty message", 2);
- return;
- }
-
- // Unpack the first TLV(5)
- unpackTypedTLV(buf, wLen, 5, &wTLVType, &wTLVLen, &pDataBuf);
- debugLogA("Message (format %u) - UID: %s", 2, strUID(dwUin, szUID));
- BYTE *pBuf = pDataBuf;
-
- // It must be TLV(5)
- if (wTLVType == 5) {
- WORD wCommand;
- oscar_tlv_chain* chain;
- oscar_tlv* tlv;
- DWORD q1, q2, q3, q4;
-
- if (wTLVLen < 26) { // just check if all basic data is there
- debugLogA("Message (format %u) - Ignoring empty message", 2);
- SAFE_FREE((void**)&pBuf);
- return;
- }
-
- unpackWord(&pDataBuf, &wCommand);
- wTLVLen -= 2;
-
- // Command 0x0000 - Normal message/file send request
- // 0x0001 - Abort request
- // 0x0002 - Acknowledge request
- debugLogA("Command is %u", wCommand);
-
- // Some stuff we don't use
- pDataBuf += 8; // dwID1 and dwID2 again
- wTLVLen -= 8;
- unpackDWord(&pDataBuf, &q1);
- unpackDWord(&pDataBuf, &q2);
- unpackDWord(&pDataBuf, &q3);
- unpackDWord(&pDataBuf, &q4); // Message Capability
- wTLVLen -= 16;
-
- if (CompareGUIDs(q1, q2, q3, q4, MCAP_SRV_RELAY_FMT)) { // we surely have at least 4 bytes for TLV chain
- MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr);
-
- if (wCommand == 1) {
- debugLogA("Cannot handle abort messages yet... :(");
- SAFE_FREE((void**)&pBuf);
- return;
- }
-
- if (wTLVLen < 4) { // just check if at least one tlv is there
- debugLogA("Message (format %u) - Ignoring empty message", 2);
- SAFE_FREE((void**)&pBuf);
- return;
- }
-
- // This TLV chain may contain the following TLVs:
- // TLV(A): Acktype 0x0000 - normal message
- // 0x0001 - file request / abort request
- // 0x0002 - file ack
- // TLV(F): Unknown
- // TLV(3): External IP
- // TLV(5): DC port (not to use for filetransfers)
- // TLV(0x2711): The next message level
-
- chain = readIntoTLVChain(&pDataBuf, wTLVLen, 0);
- if (!chain) { // sanity check
- debugLogA("Message (format %u) - Invalid data", 2);
- SAFE_FREE((void**)&pBuf);
- return;
- }
-
- WORD wAckType = chain->getWord(0x0A, 1);
-
- // Update the saved DC info (if contact already exists)
- if (hContact != INVALID_CONTACT_ID) {
- DWORD dwIP, dwExternalIP;
- WORD wPort;
-
- if (dwExternalIP = chain->getDWord(0x03, 1))
- setDword(hContact, "RealIP", dwExternalIP);
- if (dwIP = chain->getDWord(0x04, 1))
- setDword(hContact, "IP", dwIP);
- if (wPort = chain->getWord(0x05, 1))
- setWord(hContact, "UserPort", wPort);
-
- // Save tick value
- BYTE bClientID = getByte(hContact, "ClientID", 0);
- if (bClientID == CLID_GENERIC || bClientID == CLID_ICQ6)
- setDword(hContact, "TickTS", time(0) - (dwMsgID1 / 1000));
- else
- setDword(hContact, "TickTS", 0);
- }
-
- // Parse the next message level
- if (tlv = chain->getTLV(0x2711, 1))
- parseServRelayData(tlv->pData, tlv->wLen, hContact, dwUin, szUID, dwMsgID1, dwMsgID2, wAckType);
- else
- debugLogA("Warning, no 0x2711 TLV in message (format 2)");
-
- // Clean up
- disposeChain(&chain);
- }
- else if (CompareGUIDs(q1, q2, q3, q4, MCAP_REVERSE_DC_REQ)) { // Handle reverse DC request
- if (wCommand == 1) {
- debugLogA("Cannot handle abort messages yet... :(");
- SAFE_FREE((void**)&pBuf);
- return;
- }
- if (wTLVLen < 4) { // just check if at least one tlv is there
- debugLogA("Message (format %u) - Ignoring empty message", 2);
- SAFE_FREE((void**)&pBuf);
- return;
- }
- if (!dwUin) { // AIM cannot send this, just sanity
- debugLogA("Error: Malformed UIN in packet");
- SAFE_FREE((void**)&pBuf);
- return;
- }
- chain = readIntoTLVChain(&pDataBuf, wTLVLen, 0);
- if (!chain) { // Malformed packet
- debugLogA("Error: Malformed data in packet");
- SAFE_FREE((void**)&pBuf);
- return;
- }
-
- // Parse the next message level
- if (tlv = chain->getTLV(0x2711, 1)) {
- if (tlv->wLen == 0x1B) {
- BYTE *buf2 = tlv->pData;
- unpackLEDWord(&buf2, &dwUin);
-
- MCONTACT hContact = HContactFromUIN(dwUin, nullptr);
- if (hContact == INVALID_CONTACT_ID)
- debugLogA("Error: %s from unknown contact %u", "Reverse Connect Request", dwUin);
- else {
- DWORD dwIp, dwPort;
- WORD wVersion;
- BYTE bMode;
-
- unpackDWord(&buf2, &dwIp);
- unpackLEDWord(&buf2, &dwPort);
- unpackByte(&buf2, &bMode);
- buf2 += 4; // unknown
- if (dwPort)
- buf2 += 4; // port, again?
- else
- unpackLEDWord(&buf2, &dwPort);
- unpackLEWord(&buf2, &wVersion);
-
- setDword(hContact, "IP", dwIp);
- setWord(hContact, "UserPort", (WORD)dwPort);
- setByte(hContact, "DCType", bMode);
- setWord(hContact, "Version", wVersion);
- if (wVersion > 6) {
- cookie_reverse_connect *pCookie = (cookie_reverse_connect*)SAFE_MALLOC(sizeof(cookie_reverse_connect));
-
- unpackLEDWord(&buf2, (DWORD*)&pCookie->ft);
- pCookie->dwMsgID1 = dwMsgID1;
- pCookie->dwMsgID2 = dwMsgID2;
-
- OpenDirectConnection(hContact, DIRECTCONN_REVERSE, (void*)pCookie);
- }
- else debugLogA("Warning: Unsupported direct protocol version in %s", "Reverse Connect Request");
- }
- }
- else debugLogA("Malformed %s", "Reverse Connect Request");
- }
- else debugLogA("Warning, no 0x2711 TLV in message (format 2)");
-
- // Clean up
- disposeChain(&chain);
- }
- else if (CompareGUIDs(q1, q2, q3, q4, MCAP_FILE_TRANSFER)) // this is an OFT packet
- handleRecvServMsgOFT(pDataBuf, wTLVLen, dwUin, szUID, dwMsgID1, dwMsgID2, wCommand);
-
- else if (CompareGUIDs(q1, q2, q3, q4, MCAP_CONTACTS)) // this is Contacts Transfer
- handleRecvServMsgContacts(pDataBuf, wTLVLen, dwUin, szUID, dwMsgID1, dwMsgID2, wCommand);
-
- else // here should be detection of extra data streams (Xtraz)
- debugLogA("Unknown Message Format Capability");
- }
- else debugLogA("Unsupported TLV (%u) in message (format %u)", wTLVType, 2);
-
- SAFE_FREE((void**)&pBuf);
-}
-
-
-void CIcqProto::parseServRelayData(BYTE *pDataBuf, size_t wLen, MCONTACT hContact, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wAckType)
-{
- WORD wId;
-
- if (wLen < 2) {
- debugLogA("Message (format %u) - Ignoring empty message", 2);
- return;
- }
-
- unpackLEWord(&pDataBuf, &wId); // Incorrect identification, but working
- wLen -= 2;
-
- // Only 0x1B are real messages
- if (wId == 0x001B) {
- WORD wVersion;
- WORD wCookie;
- DWORD dwGuid1, dwGuid2, dwGuid3, dwGuid4;
-
- if (wLen < 31) { // just check if we have data to work with
- debugLogA("Message (format %u) - Ignoring empty message", 2);
- return;
- }
-
- unpackLEWord(&pDataBuf, &wVersion);
- wLen -= 2;
-
- if (hContact != INVALID_CONTACT_ID)
- setWord(hContact, "Version", wVersion);
-
- unpackDWord(&pDataBuf, &dwGuid1); // plugin type GUID
- unpackDWord(&pDataBuf, &dwGuid2);
- unpackDWord(&pDataBuf, &dwGuid3);
- unpackDWord(&pDataBuf, &dwGuid4);
- wLen -= 16;
-
- // Skip lots of unused stuff
- pDataBuf += 9;
- wLen -= 9;
-
- unpackLEWord(&pDataBuf, &wId);
- wLen -= 2;
-
- unpackLEWord(&pDataBuf, &wCookie);
- wLen -= 2;
-
- if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PSIG_MESSAGE)) { // is this a normal message ?
- BYTE bMsgType;
- BYTE bFlags;
- WORD wStatus, wPritority;
- WORD wMsgLen;
-
- if (wLen < 20) { // check if there is everything that should be there
- debugLogA("Message (format %u) - Ignoring empty message", 2);
- return;
- }
-
- pDataBuf += 12; /* all zeroes */
- wLen -= 12;
- unpackByte(&pDataBuf, &bMsgType);
- wLen -= 1;
- unpackByte(&pDataBuf, &bFlags);
- wLen -= 1;
-
- // Status
- unpackLEWord(&pDataBuf, &wStatus);
- wLen -= 2;
-
- // Priority
- unpackLEWord(&pDataBuf, &wPritority);
- wLen -= 2;
- debugLogA("Priority: %u", wPritority);
-
- // Message
- unpackLEWord(&pDataBuf, &wMsgLen);
- wLen -= 2;
-
- // HANDLERS
- switch (bMsgType) { // File messages, handled by the file module
- case MTYPE_FILEREQ:
- if (!dwUin) { // AIM cannot send this, just sanity
- debugLogA("Error: Malformed UIN in packet");
- return;
- }
- {
- char* szMsg = (char *)_alloca(wMsgLen + 1);
- memcpy(szMsg, pDataBuf, wMsgLen);
- szMsg[wMsgLen] = '\0';
- pDataBuf += wMsgLen;
- wLen -= wMsgLen;
-
- if (wAckType == 0 || wAckType == 1)
- // File requests 7
- handleFileRequest(pDataBuf, dwUin, wCookie, dwMsgID1, dwMsgID2, szMsg, 7, FALSE);
- else if (wAckType == 2)
- // File reply 7
- handleFileAck(pDataBuf, wLen, dwUin, wCookie, wStatus);
- else
- debugLogA("Ignored strange file message");
- }
- break;
-
- // Chat messages, handled by the chat module
- case MTYPE_CHAT:
- // TODO: this type is deprecated
- break;
-
- // Plugin messages, need further parsing
- case MTYPE_PLUGIN:
- if (wLen < wMsgLen) { // sanity check
- debugLogA("Error: Malformed server Greeting message");
- return;
- }
-
- parseServRelayPluginData(pDataBuf + wMsgLen, wLen - wMsgLen, dwUin, szUID, dwMsgID1, dwMsgID2, wAckType, bFlags, wStatus, wCookie, wVersion);
- break;
-
- // Everything else
- default:
- if (!dwUin) { // AIM cannot send this, just sanity
- debugLogA("Error: Malformed UIN in packet");
- return;
- }
-
- message_ack_params pMsgAck = { 0 };
- pMsgAck.bType = MAT_SERVER_ADVANCED;
- pMsgAck.dwUin = dwUin;
- pMsgAck.dwMsgID1 = dwMsgID1;
- pMsgAck.dwMsgID2 = dwMsgID2;
- pMsgAck.wCookie = wCookie;
- pMsgAck.msgType = bMsgType;
- pMsgAck.bFlags = bFlags;
- handleMessageTypes(dwUin, szUID, time(0), dwMsgID1, dwMsgID2, wCookie, wVersion, bMsgType, bFlags, wAckType, wLen, wMsgLen, (char*)pDataBuf, 0, &pMsgAck);
- break;
- }
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PSIG_INFO_PLUGIN)) { // info manager plugin - obsolete
- if (!dwUin) { // AIM cannot send this, just sanity
- debugLogA("Error: Malformed UIN in packet");
- return;
- }
-
- BYTE bMsgType;
- BYTE bLevel;
-
- pDataBuf += 16; /* unused stuff */
- wLen -= 16;
- unpackByte(&pDataBuf, &bMsgType);
- wLen -= 1;
-
- pDataBuf += 3; // unknown
- wLen -= 3;
- unpackByte(&pDataBuf, &bLevel);
- if (bLevel != 0 || wLen < 16) {
- debugLogA("Invalid %s Manager Plugin message from %u", "Info", dwUin);
- return;
- }
- unpackDWord(&pDataBuf, &dwGuid1); // plugin request GUID
- unpackDWord(&pDataBuf, &dwGuid2);
- unpackDWord(&pDataBuf, &dwGuid3);
- unpackDWord(&pDataBuf, &dwGuid4);
- wLen -= 16;
-
- if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PMSG_QUERY_INFO))
- debugLogA("User %u requests our %s plugin list. NOT SUPPORTED", dwUin, "info");
- else
- debugLogA("Unknown %s Manager message from %u", "Info", dwUin);
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PSIG_STATUS_PLUGIN)) { // status manager plugin - obsolete
- if (!dwUin) { // AIM cannot send this, just sanity
- debugLogA("Error: Malformed UIN in packet");
- return;
- }
-
- BYTE bMsgType;
- BYTE bLevel;
-
- pDataBuf += 16; /* unused stuff */
- wLen -= 16;
- unpackByte(&pDataBuf, &bMsgType);
- wLen -= 1;
-
- pDataBuf += 3; // unknown
- wLen -= 3;
- unpackByte(&pDataBuf, &bLevel);
- if (bLevel != 0 || wLen < 16) {
- debugLogA("Invalid %s Manager Plugin message from %u", "Status", dwUin);
- return;
- }
- unpackDWord(&pDataBuf, &dwGuid1); // plugin request GUID
- unpackDWord(&pDataBuf, &dwGuid2);
- unpackDWord(&pDataBuf, &dwGuid3);
- unpackDWord(&pDataBuf, &dwGuid4);
- wLen -= 16;
-
- if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PMSG_QUERY_STATUS))
- debugLogA("User %u requests our %s plugin list. NOT SUPPORTED", dwUin, "status");
- else
- debugLogA("Unknown %s Manager message from %u", "Status", dwUin);
- }
- else debugLogA("Unknown signature (%08x-%08x-%08x-%08x) in message (format 2)", dwGuid1, dwGuid2, dwGuid3, dwGuid4);
- }
- else debugLogA("Unknown wId1 (%u) in message (format 2)", wId);
-}
-
-void CIcqProto::parseServRelayPluginData(BYTE *pDataBuf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wAckType, BYTE bFlags, WORD wStatus, WORD wCookie, WORD wVersion)
-{
- int nTypeId;
- WORD wFunction;
-
- debugLogA("Parsing Greeting message through server");
-
- // Message plugin identification
- if (!unpackPluginTypeId(&pDataBuf, &wLen, &nTypeId, &wFunction, FALSE)) return;
-
- if (wLen > 8) {
- size_t dwLengthToEnd, dwDataLen;
-
- // Length of remaining data
- unpackLEDWord(&pDataBuf, &dwLengthToEnd);
-
- // Length of message
- unpackLEDWord(&pDataBuf, &dwDataLen);
- wLen -= 8;
-
- if (dwDataLen > wLen)
- dwDataLen = wLen;
-
- if (nTypeId == MTYPE_FILEREQ && wAckType == 2) {
- if (!dwUin) { // AIM cannot send this, just sanity
- debugLogA("Error: Malformed UIN in packet");
- return;
- }
- debugLogA("This is file ack");
-
- char *szMsg = (char *)_alloca(dwDataLen + 1);
- memcpy(szMsg, pDataBuf, dwDataLen);
- szMsg[dwDataLen] = '\0';
- pDataBuf += dwDataLen;
- wLen -= dwDataLen;
-
- handleFileAck(pDataBuf, wLen, dwUin, wCookie, wStatus);
- }
- else if (nTypeId == MTYPE_FILEREQ && wAckType == 1) {
- if (!dwUin) { // AIM cannot send this, just sanity
- debugLogA("Error: Malformed UIN in packet");
- return;
- }
- debugLogA("This is a file request");
-
- char *szMsg = (char *)_alloca(dwDataLen + 1);
- memcpy(szMsg, pDataBuf, dwDataLen);
- szMsg[dwDataLen] = '\0';
- pDataBuf += dwDataLen;
- wLen -= dwDataLen;
-
- handleFileRequest(pDataBuf, dwUin, wCookie, dwMsgID1, dwMsgID2, szMsg, 8, FALSE);
- }
- else if (nTypeId == MTYPE_CHAT && wAckType == 1) { // TODO: this is deprecated
- if (!dwUin) { // AIM cannot send this, just sanity
- debugLogA("Error: Malformed UIN in packet");
- return;
- }
- debugLogA("This is a chat request");
-
- char *szMsg = (char *)_alloca(dwDataLen + 1);
- memcpy(szMsg, pDataBuf, dwDataLen);
- szMsg[dwDataLen] = '\0';
- pDataBuf += dwDataLen;
- wLen -= dwDataLen;
-
- // handleChatRequest(pDataBuf, wLen, dwUin, wCookie, dwMsgID1, dwMsgID2, szMsg, 8);
- }
- else if (nTypeId == MTYPE_STATUSMSGEXT && wFunction >= 1 && wFunction <= 3) { // handle extended status message request
- int nMsgType = 0;
-
- switch (wFunction) {
- case 1: // Away
- if (m_iStatus == ID_STATUS_ONLINE || m_iStatus == ID_STATUS_INVISIBLE)
- nMsgType = MTYPE_AUTOONLINE;
- else if (m_iStatus == ID_STATUS_AWAY)
- nMsgType = MTYPE_AUTOAWAY;
- else if (m_iStatus == ID_STATUS_FREECHAT)
- nMsgType = MTYPE_AUTOFFC;
- break;
-
- case 2: // Busy
- if (m_iStatus == ID_STATUS_OCCUPIED)
- nMsgType = MTYPE_AUTOBUSY;
- else if (m_iStatus == ID_STATUS_DND)
- nMsgType = MTYPE_AUTODND;
- break;
-
- case 3: // N/A
- if (m_iStatus == ID_STATUS_NA)
- nMsgType = MTYPE_AUTONA;
- }
- handleMessageTypes(dwUin, szUID, time(0), dwMsgID1, dwMsgID2, wCookie, wVersion, nMsgType, bFlags, wAckType, dwLengthToEnd, 0, (char*)pDataBuf, MTF_PLUGIN | MTF_STATUS_EXTENDED, nullptr);
- }
- else if (nTypeId) {
- if (!dwUin) { // AIM cannot send this, just sanity
- debugLogA("Error: Malformed UIN in packet");
- return;
- }
- message_ack_params pMsgAck = { 0 };
-
- pMsgAck.bType = MAT_SERVER_ADVANCED;
- pMsgAck.dwUin = dwUin;
- pMsgAck.dwMsgID1 = dwMsgID1;
- pMsgAck.dwMsgID2 = dwMsgID2;
- pMsgAck.wCookie = wCookie;
- pMsgAck.msgType = nTypeId;
- pMsgAck.bFlags = bFlags;
- handleMessageTypes(dwUin, szUID, time(0), dwMsgID1, dwMsgID2, wCookie, wVersion, nTypeId, bFlags, wAckType, dwLengthToEnd, dwDataLen, (char*)pDataBuf, MTF_PLUGIN, &pMsgAck);
- }
- else debugLogA("Unsupported plugin message type %d", nTypeId);
- }
- else debugLogA("Error: Malformed server plugin message");
-}
-
-void CIcqProto::handleRecvServMsgContacts(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwID1, DWORD dwID2, WORD wCommand)
-{
- MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr);
-
- if (wCommand == 0) { // received contacts
- if (wLen < 4) { // just check if at least one tlv is there
- debugLogA("Message (format %u) - Ignoring empty contacts message", 2);
- return;
- }
- oscar_tlv_chain *chain = readIntoTLVChain(&buf, wLen, 0);
- if (!chain) { // sanity check
- debugLogA("Message (format %u) - Invalid data", 2);
- return;
- }
-
- WORD wAckType = chain->getWord(0x0A, 1);
-
- if (wAckType == 1) { // it is really message containing contacts, parse them
- oscar_tlv *tlvUins = chain->getTLV(0x2711, 1);
- oscar_tlv *tlvNames = chain->getTLV(0x2712, 1);
-
- if (!tlvUins || tlvUins->wLen < 4) {
- debugLogA("Malformed '%s' message", "contacts");
- disposeChain(&chain);
- return;
- }
- int nContacts = 0x10, iContact = 0;
- ICQSEARCHRESULT **contacts = (ICQSEARCHRESULT**)SAFE_MALLOC(nContacts * sizeof(ICQSEARCHRESULT*));
- WORD wContactsGroup = 0;
- int valid = 1;
- BYTE *pBuffer = tlvUins->pData;
- int nLen = tlvUins->wLen;
-
- while (nLen > 2) { // parse UIDs
- if (!wContactsGroup) {
- WORD wGroupLen;
-
- unpackWord(&pBuffer, &wGroupLen);
- nLen -= 2;
- if (nLen >= wGroupLen + 2) {
- pBuffer += wGroupLen;
- unpackWord(&pBuffer, &wContactsGroup);
- nLen -= wGroupLen + 2;
- }
- else
- break;
- }
- else { // group parsed, UIDs waiting
- WORD wUidLen;
-
- unpackWord(&pBuffer, &wUidLen);
- nLen -= 2;
- if (nLen >= wUidLen) {
- char *szUid = (char*)SAFE_MALLOC(wUidLen + 1);
- unpackString(&pBuffer, szUid, wUidLen);
- nLen -= wUidLen;
-
- if (iContact >= nContacts) { // the list is too small, resize it
- nContacts += 0x10;
- contacts = (ICQSEARCHRESULT**)SAFE_REALLOC(contacts, nContacts * sizeof(ICQSEARCHRESULT*));
- }
- contacts[iContact] = (ICQSEARCHRESULT*)SAFE_MALLOC(sizeof(ICQSEARCHRESULT));
- contacts[iContact]->hdr.cbSize = sizeof(ICQSEARCHRESULT);
- contacts[iContact]->hdr.flags = PSR_UNICODE;
- contacts[iContact]->hdr.nick.w = null_strdup(L"");
- contacts[iContact]->hdr.id.w = ansi_to_unicode(szUid);
-
- if (IsStringUIN(szUid)) { // icq contact
- contacts[iContact]->uin = atoi(szUid);
- if (contacts[iContact]->uin == 0)
- valid = 0;
- }
- else { // aim contact
- if (!mir_strlen(szUid))
- valid = 0;
- }
- iContact++;
-
- SAFE_FREE(&szUid);
- }
- else {
- if (wContactsGroup) valid = 0;
- break;
- }
-
- wContactsGroup--;
- }
- }
- if (!iContact || !valid) {
- debugLogA("Malformed '%s' message", "contacts");
- disposeChain(&chain);
- for (int i = 0; i < iContact; i++) {
- SAFE_FREE(&contacts[i]->hdr.id.w);
- SAFE_FREE(&contacts[i]->hdr.nick.w);
- SAFE_FREE((void**)&contacts[i]);
- }
- SAFE_FREE((void**)&contacts);
- return;
- }
- nContacts = iContact;
- if (tlvNames && tlvNames->wLen >= 4) { // parse names, if available
- pBuffer = tlvNames->pData;
- nLen = tlvNames->wLen;
- iContact = 0;
-
- while (nLen > 2) { // parse Names
- if (!wContactsGroup) {
- WORD wGroupLen;
-
- unpackWord(&pBuffer, &wGroupLen);
- nLen -= 2;
- if (nLen >= wGroupLen + 2) {
- pBuffer += wGroupLen;
- unpackWord(&pBuffer, &wContactsGroup);
- nLen -= wGroupLen + 2;
- }
- else
- break;
- }
- else { // group parsed, Names waiting
- WORD wNickLen;
-
- unpackWord(&pBuffer, &wNickLen);
- nLen -= 2;
- if (nLen >= wNickLen) {
- WORD wNickTLV;
- size_t wNickTLVLen;
- char *pNick = nullptr;
-
- unpackTypedTLV(pBuffer, wNickLen, 0x01, &wNickTLV, &wNickTLVLen, (LPBYTE*)&pNick);
- if (wNickTLV == 0x01) {
- SAFE_FREE(&contacts[iContact]->hdr.nick.w);
- contacts[iContact]->hdr.nick.w = make_unicode_string(pNick);
- }
- else
- SAFE_FREE(&pNick);
- pBuffer += wNickLen;
- nLen -= wNickLen;
-
- iContact++;
- if (iContact >= nContacts) break;
- }
- else
- break;
-
- wContactsGroup--;
- }
- }
- }
-
- if (!valid)
- debugLogA("Malformed '%s' message", "contacts");
- else {
- int bAdded;
- hContact = HContactFromUID(dwUin, szUID, &bAdded);
-
- // ack the message
- icq_sendContactsAck(dwUin, szUID, dwID1, dwID2);
-
- PROTORECVEVENT pre = { 0 };
- pre.timestamp = (DWORD)time(0);
- pre.szMessage = (char *)contacts;
- pre.lParam = nContacts;
- ProtoChainRecv(hContact, PSR_CONTACTS, 0, (LPARAM)&pre);
- }
-
- for (int i = 0; i < iContact; i++) {
- SAFE_FREE(&contacts[i]->hdr.id.w);
- SAFE_FREE(&contacts[i]->hdr.nick.w);
- SAFE_FREE((void**)&contacts[i]);
- }
- SAFE_FREE((void**)&contacts);
- }
- else
- debugLogA("Error: Received unknown contacts message, ignoring.");
- // Clean up
- disposeChain(&chain);
- }
- else if (wCommand == 1) {
- debugLogA("Cannot handle abort messages yet... :(");
- }
- else if (wCommand == 2) { // acknowledgement
- DWORD dwCookie;
- MCONTACT hCookieContact;
- if (FindMessageCookie(dwID1, dwID2, &dwCookie, &hCookieContact, nullptr)) {
- if (hCookieContact != hContact)
- debugLogA("Warning: Ack Contact does not match Cookie Contact(0x%x != 0x%x)", hContact, hCookieContact);
-
- ProtoBroadcastAck(hContact, ACKTYPE_CONTACTS, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0);
-
- ReleaseCookie(dwCookie);
- }
- else debugLogA("Warning: Unexpected Contact Transfer ack from %s", strUID(dwUin, szUID));
- }
-}
-
-void CIcqProto::handleRecvServMsgType4(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, DWORD dwRef)
-{
- WORD wTLVType;
- size_t wTLVLen;
- BYTE* pDataBuf;
- DWORD dwUin2;
-
- if (wLen < 2) {
- debugLogA("Message (format %u) - Ignoring empty message", 4);
- return;
- }
-
- // Unpack the first TLV(5)
- unpackTypedTLV(buf, wLen, 5, &wTLVType, &wTLVLen, &pDataBuf);
- debugLogA("Message (format %u) - UID: %s", 4, strUID(dwUin, szUID));
-
- // It must be TLV(5)
- if (wTLVType == 5) {
- BYTE bMsgType;
- BYTE bFlags;
- BYTE* pmsg = pDataBuf;
- size_t wMsgLen;
-
- unpackLEDWord(&pmsg, &dwUin2);
-
- if (dwUin2 == dwUin) {
- unpackByte(&pmsg, &bMsgType);
- unpackByte(&pmsg, &bFlags);
- unpackLEWord(&pmsg, &wMsgLen);
-
- if (bMsgType == 0 && wMsgLen == 1)
- debugLogA("User %u probably checks his ignore state.", dwUin);
- else {
- cookie_offline_messages *cookie;
- DWORD dwRecvTime = (DWORD)time(0);
-
- if (!(dwRef & 0x80000000) && FindCookie(dwRef, nullptr, (void**)&cookie)) {
- WORD wTimeTLVType;
- size_t wTimeTLVLen;
- BYTE *pTimeTLV = nullptr;
-
- cookie->nMessages++;
-
- unpackTypedTLV(buf, wLen, 0x16, &wTimeTLVType, &wTimeTLVLen, &pTimeTLV);
- if (pTimeTLV && wTimeTLVType == 0x16 && wTimeTLVLen == 4) { // found Offline timestamp
- BYTE *pBuf = pTimeTLV;
- unpackDWord(&pBuf, &dwRecvTime);
- debugLogA("Message (format %u) - Offline timestamp is %s", 4, time2text(dwRecvTime));
- }
- SAFE_FREE((void**)&pTimeTLV);
- }
-
- if (bMsgType == MTYPE_PLUGIN) {
- wLen = wTLVLen - 8;
-
- debugLogA("Parsing Greeting message through server");
-
- pmsg += wMsgLen;
- wLen -= wMsgLen;
-
- int typeId;
- if (unpackPluginTypeId(&pmsg, &wLen, &typeId, nullptr, FALSE) && wLen > 8) {
- size_t dwLengthToEnd, dwDataLen;
-
- // Length of remaining data
- unpackLEDWord(&pmsg, &dwLengthToEnd);
-
- // Length of message
- unpackLEDWord(&pmsg, &dwDataLen);
- wLen -= 8;
-
- if (dwDataLen > wLen)
- dwDataLen = wLen;
-
- if (typeId) {
- uid_str szUid;
- handleMessageTypes(dwUin, szUid, dwRecvTime, dwMsgID1, dwMsgID2, 0, 0, typeId, bFlags, 0, dwLengthToEnd, dwDataLen, (char*)pmsg, MTF_PLUGIN, nullptr);
- }
- else debugLogA("Unsupported plugin message type %d", typeId);
- }
- }
- else {
- uid_str szUid;
- handleMessageTypes(dwUin, szUid, dwRecvTime, dwMsgID1, dwMsgID2, 0, 0, bMsgType, bFlags, 0, wTLVLen - 8, wMsgLen, (char*)pmsg, 0, nullptr);
- }
- }
- }
- else debugLogA("Ignoring spoofed TYPE4 message thru server from %d", dwUin);
- }
- else debugLogA("Unsupported TLV (%u) in message (format %u)", wTLVType, 4);
-
- SAFE_FREE((void**)&pDataBuf);
-}
-
-
-//
-// Helper functions
-//
-
-static int TypeGUIDToTypeId(DWORD dwGuid1, DWORD dwGuid2, DWORD dwGuid3, DWORD dwGuid4, WORD wType)
-{
- int nTypeID = MTYPE_UNKNOWN;
-
- if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_STATUSMSGEXT)) {
- nTypeID = MTYPE_STATUSMSGEXT;
- }
- else if (wType == MGTYPE_UNDEFINED) {
- if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PSIG_MESSAGE)) { // icq6 message ack
- nTypeID = MTYPE_PLAIN;
- }
- }
- else if (wType == MGTYPE_STANDARD_SEND) {
- if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_WEBURL)) {
- nTypeID = MTYPE_URL;
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_CONTACTS)) {
- nTypeID = MTYPE_CONTACTS;
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_CHAT)) {
- nTypeID = MTYPE_CHAT;
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_FILE)) {
- nTypeID = MTYPE_FILEREQ;
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_GREETING_CARD)) {
- nTypeID = MTYPE_GREETINGCARD;
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_MESSAGE)) {
- nTypeID = MTYPE_MESSAGE;
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_SMS_MESSAGE)) {
- nTypeID = MTYPE_SMS_MESSAGE;
- }
- }
- else if (wType == MGTYPE_CONTACTS_REQUEST) {
- if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_CONTACTS)) {
- nTypeID = MTYPE_REQUESTCONTACTS;
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_XTRAZ_SCRIPT)) {
- nTypeID = MTYPE_SCRIPT_DATA;
- }
- }
- else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_XTRAZ_SCRIPT)) {
- if (wType == MGTYPE_SCRIPT_INVITATION) {
- nTypeID = MTYPE_SCRIPT_INVITATION;
- }
- else if (wType == MGTYPE_SCRIPT_NOTIFY) {
- nTypeID = MTYPE_SCRIPT_NOTIFY;
- }
- }
-
- return nTypeID;
-}
-
-
-int CIcqProto::unpackPluginTypeId(BYTE **pBuffer, size_t *pwLen, int *pTypeId, WORD *pFunctionId, BOOL bThruDC)
-{
- size_t wLen = *pwLen, wInfoLen, dwPluginNameLen;
- DWORD q1, q2, q3, q4;
- WORD qt;
-
- if (wLen < 24)
- return 0; // Failure
-
- unpackLEWord(pBuffer, &wInfoLen);
-
- unpackDWord(pBuffer, &q1); // get data GUID & function id
- unpackDWord(pBuffer, &q2);
- unpackDWord(pBuffer, &q3);
- unpackDWord(pBuffer, &q4);
- unpackLEWord(pBuffer, &qt);
- wLen -= 20;
-
- if (pFunctionId) *pFunctionId = qt;
-
- unpackLEDWord(pBuffer, &dwPluginNameLen);
- wLen -= 4;
-
- if (dwPluginNameLen > wLen) { // check for malformed plugin name
- dwPluginNameLen = wLen;
- NetLog_Uni(bThruDC, "Warning: malformed size of plugin name.");
- }
- char *szPluginName = (char *)_alloca(dwPluginNameLen + 1);
- memcpy(szPluginName, *pBuffer, dwPluginNameLen);
- szPluginName[dwPluginNameLen] = '\0';
- wLen -= dwPluginNameLen;
-
- *pBuffer += dwPluginNameLen;
-
- int typeId = TypeGUIDToTypeId(q1, q2, q3, q4, qt);
- if (!typeId)
- NetLog_Uni(bThruDC, "Error: Unknown type {%08x-%08x-%08x-%08x:%04x}: %s", q1, q2, q3, q4, qt, szPluginName);
-
- if (wInfoLen >= 22 + dwPluginNameLen) { // sanity checking
- wInfoLen -= 22 + dwPluginNameLen;
-
- // check if enough data is available - skip remaining bytes of info block
- if (wLen >= wInfoLen) {
- *pBuffer += wInfoLen;
- wLen -= wInfoLen;
- }
- }
-
- *pwLen = wLen;
- *pTypeId = typeId;
-
- return 1; // Success
-}
-
-
-int getPluginTypeIdLen(int nTypeID)
-{
- switch (nTypeID) {
- case MTYPE_SCRIPT_NOTIFY:
- return 0x51;
-
- case MTYPE_FILEREQ:
- return 0x2B;
-
- case MTYPE_AUTOONLINE:
- case MTYPE_AUTOAWAY:
- case MTYPE_AUTOBUSY:
- case MTYPE_AUTODND:
- case MTYPE_AUTOFFC:
- return 0x3C;
-
- case MTYPE_AUTONA:
- return 0x3B;
-
- default:
- return 0;
- }
-}
-
-
-void packPluginTypeId(icq_packet *packet, int nTypeID)
-{
- switch (nTypeID) {
- case MTYPE_SCRIPT_NOTIFY:
- packLEWord(packet, 0x04f); // Length
-
- packGUID(packet, MGTYPE_XTRAZ_SCRIPT); // Message Type GUID
- packLEWord(packet, MGTYPE_SCRIPT_NOTIFY); // Function ID
- packLEDWord(packet, 0x002a); // Request type string
- packBuffer(packet, (LPBYTE)"Script Plug-in: Remote Notification Arrive", 0x002a);
-
- packDWord(packet, 0x00000100); // Unknown binary stuff
- packDWord(packet, 0x00000000);
- packDWord(packet, 0x00000000);
- packWord(packet, 0x0000);
- packByte(packet, 0x00);
-
- break;
-
- case MTYPE_FILEREQ:
- packLEWord(packet, 0x029); // Length
-
- packGUID(packet, MGTYPE_FILE); // Message Type GUID
- packWord(packet, 0x0000); // Unknown
- packLEDWord(packet, 0x0004); // Request type string
- packBuffer(packet, (LPBYTE)"File", 0x0004);
-
- packDWord(packet, 0x00000100); // More unknown binary stuff
- packDWord(packet, 0x00010000);
- packDWord(packet, 0x00000000);
- packWord(packet, 0x0000);
- packByte(packet, 0x00);
-
- break;
-
- case MTYPE_AUTOONLINE:
- case MTYPE_AUTOAWAY:
- case MTYPE_AUTOFFC:
- packLEWord(packet, 0x03A); // Length
-
- packGUID(packet, MGTYPE_STATUSMSGEXT); // Message Type GUID
-
- packLEWord(packet, 1); // Function ID
- packLEDWord(packet, 0x13); // Request type string
- packBuffer(packet, (LPBYTE)"Away Status Message", 0x13);
-
- packDWord(packet, 0x01000000); // Unknown binary stuff
- packDWord(packet, 0x00000000);
- packDWord(packet, 0x00000000);
- packDWord(packet, 0x00000000);
- packByte(packet, 0x00);
-
- break;
-
- case MTYPE_AUTOBUSY:
- case MTYPE_AUTODND:
- packLEWord(packet, 0x03A); // Length
-
- packGUID(packet, MGTYPE_STATUSMSGEXT); // Message Type GUID
-
- packLEWord(packet, 2); // Function ID
- packLEDWord(packet, 0x13); // Request type string
- packBuffer(packet, (LPBYTE)"Busy Status Message", 0x13);
-
- packDWord(packet, 0x02000000); // Unknown binary stuff
- packDWord(packet, 0x00000000);
- packDWord(packet, 0x00000000);
- packDWord(packet, 0x00000000);
- packByte(packet, 0x00);
-
- break;
-
- case MTYPE_AUTONA:
- packLEWord(packet, 0x039); // Length
-
- packGUID(packet, MGTYPE_STATUSMSGEXT); // Message Type GUID
-
- packLEWord(packet, 3); // Function ID
- packLEDWord(packet, 0x12); // Request type string
- packBuffer(packet, (LPBYTE)"N/A Status Message", 0x12);
-
- packDWord(packet, 0x03000000); // Unknown binary stuff
- packDWord(packet, 0x00000000);
- packDWord(packet, 0x00000000);
- packDWord(packet, 0x00000000);
- packByte(packet, 0x00);
-
- break;
- }
-}
-
-
-void CIcqProto::handleStatusMsgReply(const char *szPrefix, MCONTACT hContact, DWORD dwUin, int bMsgType, WORD wCookie, const char *szMsg)
-{
- if (hContact == INVALID_CONTACT_ID) {
- debugLogA("%sIgnoring status message from unknown contact %u", szPrefix, dwUin);
- return;
- }
-
- int status = AwayMsgTypeToStatus(bMsgType);
- if (status == ID_STATUS_OFFLINE) {
- debugLogA("%sIgnoring unknown status message from %u", szPrefix, dwUin);
- return;
- }
-
- // it is probably UTF-8 status reply
- PROTORECVEVENT pre = { 0 };
- pre.szMessage = (char*)szMsg;
- pre.timestamp = time(0);
- pre.lParam = wCookie;
- ProtoChainRecv(hContact, PSR_AWAYMSG, status, (LPARAM)&pre);
-}
-
-
-HANDLE CIcqProto::handleMessageAck(DWORD dwUin, char *szUID, WORD wCookie, int type, PBYTE buf, BYTE bFlags)
-{
- if (bFlags == 3) {
- MCONTACT hCookieContact;
- cookie_message_data *pCookieData = nullptr;
-
- MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr);
-
- if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData)) {
- debugLogA("%sIgnoring unrequested status message from %u", "handleMessageAck: ", dwUin);
-
- ReleaseCookie(wCookie);
- return INVALID_HANDLE_VALUE;
- }
-
- if (hContact != hCookieContact) {
- debugLogA("%sAck Contact does not match Cookie Contact(0x%x != 0x%x)", "handleMessageAck: ", hContact, hCookieContact);
-
- ReleaseCookie(wCookie);
- return INVALID_HANDLE_VALUE;
- }
- ReleaseCookie(wCookie);
-
- handleStatusMsgReply("handleMessageAck: ", hContact, dwUin, type, wCookie, (char*)buf);
- }
- else // Should not happen
- debugLogA("%sIgnored type %u ack message (this should not happen)", "handleMessageAck: ", type);
-
- return INVALID_HANDLE_VALUE;
-}
-
-
-/* this function send all acks from handleMessageTypes */
-void CIcqProto::sendMessageTypesAck(MCONTACT hContact, int bUnicode, message_ack_params *pArgs)
-{
- if (pArgs) {
- if ((pArgs->msgType == MTYPE_PLAIN && !CallService(MS_IGNORE_ISIGNORED, hContact, IGNOREEVENT_MESSAGE))
- || (pArgs->msgType == MTYPE_URL && !CallService(MS_IGNORE_ISIGNORED, hContact, IGNOREEVENT_URL))
- || pArgs->msgType == MTYPE_CONTACTS) {
- if (pArgs->bType == MAT_SERVER_ADVANCED) { // Only ack message packets
- icq_sendAdvancedMsgAck(pArgs->dwUin, pArgs->dwMsgID1, pArgs->dwMsgID2, pArgs->wCookie, (BYTE)pArgs->msgType, pArgs->bFlags);
- }
- else if (pArgs->bType == MAT_DIRECT) { // Send acknowledgement
- icq_sendDirectMsgAck(pArgs->pDC, pArgs->wCookie, (BYTE)pArgs->msgType, pArgs->bFlags, bUnicode ? (char *)CAP_UTF8MSGS : nullptr);
- }
- }
- }
-}
-
-
-/* this function also processes direct packets, so it should be bulletproof */
-/* pMsg points to the beginning of the message */
-void CIcqProto::handleMessageTypes(DWORD dwUin, char *szUID, DWORD dwTimestamp, DWORD dwMsgID, DWORD dwMsgID2, WORD wCookie, WORD wVersion, int type, int flags, WORD wAckType, size_t dwDataLen, size_t wMsgLen, char *pMsg, int nMsgFlags, message_ack_params *pAckParams)
-{
- MCONTACT hContact = INVALID_CONTACT_ID;
- BOOL bThruDC = (nMsgFlags & MTF_DIRECT) == MTF_DIRECT;
- int bAdded;
-
- if (dwDataLen < wMsgLen) {
- NetLog_Uni(bThruDC, "Ignoring overflowed message");
- return;
- }
-
- if (wAckType == 2) {
- handleMessageAck(dwUin, szUID, wCookie, type, (LPBYTE)pMsg, (BYTE)flags);
- return;
- }
-
- char *szMsg = (char *)SAFE_MALLOC(wMsgLen + 1);
- if (wMsgLen > 0) {
- memcpy(szMsg, pMsg, wMsgLen);
- pMsg += wMsgLen;
- dwDataLen -= wMsgLen;
- }
- szMsg[wMsgLen] = '\0';
-
-
- char *pszMsgField[2 * MAX_CONTACTSSEND + 1];
- int nMsgFields = 0;
-
- pszMsgField[0] = szMsg;
- if (type == MTYPE_URL || type == MTYPE_AUTHREQ || type == MTYPE_ADDED || type == MTYPE_CONTACTS || type == MTYPE_EEXPRESS || type == MTYPE_WWP) {
- nMsgFields = 1;
- for (char *pszMsg = szMsg; *pszMsg; pszMsg++) {
- if ((BYTE)*pszMsg == 0xFE) {
- *pszMsg = '\0';
- pszMsgField[nMsgFields++] = pszMsg + 1;
- if (nMsgFields >= _countof(pszMsgField))
- break;
- }
- }
- }
-
- switch (type) {
- case MTYPE_PLAIN: /* plain message */
- {
- PROTORECVEVENT pre = { 0 };
- bool bUtf8 = false;
-
- // Check if this message is marked as UTF8 encoded
- if (dwDataLen > 12) {
- DWORD dwGuidLen = 0;
- int bDoubleMsg = 0;
-
- if (bThruDC) {
- DWORD dwExtraLen = *(DWORD*)pMsg;
-
- if (dwExtraLen < dwDataLen && !strncmp(szMsg, "{\\rtf", 5)) { // it is icq5 sending us crap, get real message from it
- WCHAR* usMsg = (WCHAR*)_alloca((dwExtraLen + 1) * sizeof(WCHAR));
- // make sure it is null-terminated
- wcsncpy(usMsg, (WCHAR*)(pMsg + 4), dwExtraLen);
- usMsg[dwExtraLen] = '\0';
- SAFE_FREE(&szMsg);
- szMsg = (char*)make_utf8_string(usMsg);
-
- if (!IsUnicodeAscii(usMsg, dwExtraLen))
- bUtf8 = true; // only mark real non-ascii messages as unicode
-
- bDoubleMsg = 1;
- }
- }
-
- if (!bDoubleMsg) {
- dwGuidLen = *(DWORD*)(pMsg + 8);
- dwDataLen -= 12;
- pMsg += 12;
- }
-
- while ((dwGuidLen >= 38) && (dwDataLen >= dwGuidLen)) {
- if (!strncmp(pMsg, CAP_UTF8MSGS, 38)) { // Found UTF8 cap, convert message to ansi
- bUtf8 = true;
- break;
- }
- else if (!strncmp(pMsg, CAP_RTFMSGS, 38)) { // Found RichText cap
- NetLog_Uni(bThruDC, "Warning: User %u sends us RichText.", dwUin);
- break;
- }
-
- dwGuidLen -= 38;
- dwDataLen -= 38;
- pMsg += 38;
- }
- }
-
- hContact = HContactFromUIN(dwUin, &bAdded);
- sendMessageTypesAck(hContact, bUtf8, pAckParams);
-
- if (!bUtf8 && !IsUSASCII(szMsg, mir_strlen(szMsg))) { // message is Ansi and contains national characters, create Unicode part by codepage
- char *usMsg = convertMsgToUserSpecificUtf(hContact, szMsg);
- if (usMsg) {
- SAFE_FREE(&szMsg);
- szMsg = (char*)usMsg;
- }
- }
-
- pre.timestamp = dwTimestamp;
- pre.szMessage = (char *)szMsg;
- ProtoChainRecvMsg(hContact, &pre);
- }
- break;
-
- case MTYPE_URL:
- if (nMsgFields < 2) {
- NetLog_Uni(bThruDC, "Malformed '%s' message", "URL");
- break;
- }
-
- hContact = HContactFromUIN(dwUin, &bAdded);
- sendMessageTypesAck(hContact, 0, pAckParams);
- {
- char *szTitle = ICQTranslateUtf(LPGEN("Incoming URL:"));
- char *szDataDescr = ansi_to_utf8(pszMsgField[0]);
- char *szDataUrl = ansi_to_utf8(pszMsgField[1]);
- char *szBlob = (char *)SAFE_MALLOC(mir_strlen(szTitle) + mir_strlen(szDataDescr) + mir_strlen(szDataUrl) + 8);
- mir_strcpy(szBlob, szTitle);
- mir_strcat(szBlob, " ");
- mir_strcat(szBlob, szDataDescr); // Description
- mir_strcat(szBlob, "\r\n");
- mir_strcat(szBlob, szDataUrl); // URL
- SAFE_FREE(&szTitle);
- SAFE_FREE(&szDataDescr);
- SAFE_FREE(&szDataUrl);
-
- PROTORECVEVENT pre = { 0 };
- pre.timestamp = dwTimestamp;
- pre.szMessage = (char *)szBlob;
- ProtoChainRecvMsg(hContact, &pre);
- SAFE_FREE(&szBlob);
- }
- break;
-
- case MTYPE_AUTHREQ: /* auth request */
- /* format: nick FE first FE last FE email FE unk-char FE msg 00 */
- if (nMsgFields < 6) {
- debugLogA("Malformed '%s' message", "auth req");
- break;
- }
- {
- DB_AUTH_BLOB blob(hContact, pszMsgField[0], pszMsgField[1], pszMsgField[2], pszMsgField[3], pszMsgField[5]);
- blob.set_uin(dwUin);
-
- PROTORECVEVENT pre = { 0 };
- pre.timestamp = dwTimestamp;
- pre.lParam = blob.size();
- pre.szMessage = blob;
- ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre);
- }
- break;
-
- case MTYPE_ADDED: /* 'you were added' */
- /* format: nick FE first FE last FE email 00 */
- if (nMsgFields < 4) {
- debugLogA("Malformed '%s' message", "you were added");
- break;
- }
- hContact = HContactFromUIN(dwUin, &bAdded);
- {
- // blob is: uin(DWORD), hcontact(HANDLE), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ)
- size_t cbBlob = sizeof(DWORD) * 2 + mir_strlen(pszMsgField[0]) + mir_strlen(pszMsgField[1]) + mir_strlen(pszMsgField[2]) + mir_strlen(pszMsgField[3]) + 4;
- PBYTE pBlob, pCurBlob = pBlob = (PBYTE)_alloca(cbBlob);
- *(DWORD*)pCurBlob = dwUin; pCurBlob += sizeof(DWORD);
- *(DWORD*)pCurBlob = DWORD(hContact); pCurBlob += sizeof(DWORD);
- mir_strcpy((char*)pCurBlob, pszMsgField[0]); pCurBlob += mir_strlen((char*)pCurBlob) + 1;
- mir_strcpy((char*)pCurBlob, pszMsgField[1]); pCurBlob += mir_strlen((char*)pCurBlob) + 1;
- mir_strcpy((char*)pCurBlob, pszMsgField[2]); pCurBlob += mir_strlen((char*)pCurBlob) + 1;
- mir_strcpy((char*)pCurBlob, pszMsgField[3]);
- AddEvent(NULL, EVENTTYPE_ADDED, dwTimestamp, 0, cbBlob, pBlob);
- }
- break;
-
- case MTYPE_CONTACTS:
- {
- char* pszNContactsEnd;
- int nContacts;
- if (nMsgFields < 3 ||
- (nContacts = strtol(pszMsgField[0], &pszNContactsEnd, 10)) == 0 ||
- pszNContactsEnd - pszMsgField[0] != (int)mir_strlen(pszMsgField[0]) ||
- nMsgFields < nContacts * 2 + 1) {
- NetLog_Uni(bThruDC, "Malformed '%s' message", "contacts");
- }
- else {
- int valid = 1;
- ICQSEARCHRESULT** isrList = (ICQSEARCHRESULT**)_alloca(nContacts * sizeof(ICQSEARCHRESULT*));
- for (int i = 0; i < nContacts; i++) {
- isrList[i] = (ICQSEARCHRESULT*)SAFE_MALLOC(sizeof(ICQSEARCHRESULT));
- isrList[i]->hdr.cbSize = sizeof(ICQSEARCHRESULT);
- isrList[i]->hdr.flags = PSR_UNICODE;
- if (IsStringUIN(pszMsgField[1 + i * 2])) { // icq contact
- isrList[i]->uin = atoi(pszMsgField[1 + i * 2]);
- if (isrList[i]->uin == 0)
- valid = 0;
- }
- else { // aim contact
- if (!mir_strlen(pszMsgField[1 + i * 2]))
- valid = 0;
- }
- isrList[i]->hdr.id.w = ansi_to_unicode(pszMsgField[1 + i * 2]);
- isrList[i]->hdr.nick.w = ansi_to_unicode(pszMsgField[2 + i * 2]);
- }
-
- if (!valid)
- NetLog_Uni(bThruDC, "Malformed '%s' message", "contacts");
- else {
- hContact = HContactFromUIN(dwUin, &bAdded);
- sendMessageTypesAck(hContact, 0, pAckParams);
-
- PROTORECVEVENT pre = { 0 };
- pre.timestamp = dwTimestamp;
- pre.szMessage = (char *)isrList;
- pre.lParam = nContacts;
- ProtoChainRecv(hContact, PSR_CONTACTS, 0, (LPARAM)&pre);
- }
-
- for (int i = 0; i < nContacts; i++) {
- SAFE_FREE(&isrList[i]->hdr.id.w);
- SAFE_FREE(&isrList[i]->hdr.nick.w);
- SAFE_FREE((void**)&isrList[i]);
- }
- }
- }
- break;
-
- case MTYPE_PLUGIN: // FIXME: this should be removed - it is never called
- hContact = NULL;
-
- switch (dwUin) {
- case 1111: /* icqmail 'you've got mail' - not processed */
- break;
- }
- break;
-
- case MTYPE_SMS_MESSAGE:
- // it's a SMS message from a mobile - broadcast to SMS plugin
- if (dwUin != 1002) {
- NetLog_Uni(bThruDC, "Malformed '%s' message", "SMS Mobile");
- break;
- }
- debugLogA("Received SMS Mobile message");
-
- ProtoBroadcastAck(NULL, ICQACKTYPE_SMS, ACKRESULT_SUCCESS, nullptr, (LPARAM)szMsg);
- break;
-
- case MTYPE_STATUSMSGEXT:
- // it's either extended StatusMsg reply from icq2003b or a IcqWebMessage
- if (dwUin == 1003)
- debugLogA("Received ICQWebMessage - NOT SUPPORTED");
- break;
-
- case MTYPE_WWP:
- // format: fromname FE FE FE fromemail FE unknownbyte FE 'Sender IP: xxx.xxx.xxx.xxx' 0D 0A body
- if (nMsgFields < 6)
- debugLogA("Malformed '%s' message", "web pager");
- else {
- // blob is: body(ASCIIZ), name(ASCIIZ), email(ASCIIZ)
- size_t cbBlob = mir_strlen(pszMsgField[0]) + mir_strlen(pszMsgField[3]) + mir_strlen(pszMsgField[5]) + 3;
- PBYTE pBlob, pCurBlob = pBlob = (PBYTE)_alloca(cbBlob);
- mir_strcpy((char *)pCurBlob, pszMsgField[5]); pCurBlob += mir_strlen((char *)pCurBlob) + 1;
- mir_strcpy((char *)pCurBlob, pszMsgField[0]); pCurBlob += mir_strlen((char *)pCurBlob) + 1;
- mir_strcpy((char *)pCurBlob, pszMsgField[3]);
-
- AddEvent(NULL, ICQEVENTTYPE_WEBPAGER, dwTimestamp, 0, cbBlob, pBlob);
- }
- break;
-
- case MTYPE_EEXPRESS:
- // format: fromname FE FE FE fromemail FE unknownbyte FE body
- if (nMsgFields < 6)
- debugLogA("Malformed '%s' message", "e-mail express");
- else {
- // blob is: body(ASCIIZ), name(ASCIIZ), email(ASCIIZ)
- size_t cbBlob = mir_strlen(pszMsgField[0]) + mir_strlen(pszMsgField[3]) + mir_strlen(pszMsgField[5]) + 3;
- PBYTE pBlob, pCurBlob = pBlob = (PBYTE)_alloca(cbBlob);
- mir_strcpy((char *)pCurBlob, pszMsgField[5]); pCurBlob += mir_strlen((char *)pCurBlob) + 1;
- mir_strcpy((char *)pCurBlob, pszMsgField[0]); pCurBlob += mir_strlen((char *)pCurBlob) + 1;
- mir_strcpy((char *)pCurBlob, pszMsgField[3]);
-
- AddEvent(NULL, ICQEVENTTYPE_EMAILEXPRESS, dwTimestamp, 0, cbBlob, pBlob);
- }
- break;
-
- case MTYPE_REQUESTCONTACTS:
- /* it's a contacts-request */
- NetLog_Uni(bThruDC, "Received %s from %u", "Request for Contacts", dwUin);
- break;
-
- case MTYPE_GREETINGCARD:
- /* it's a greeting card */
- NetLog_Uni(bThruDC, "Received %s from %u", "Greeting Card", dwUin);
- break;
-
- case MTYPE_SCRIPT_NOTIFY:
- /* it's a xtraz notify request */
- NetLog_Uni(bThruDC, "Received %s from %u", "Xtraz Notify Request", dwUin);
- handleXtrazNotify(dwUin, dwMsgID, dwMsgID2, wCookie, szMsg, wMsgLen, bThruDC);
- break;
-
- case MTYPE_SCRIPT_INVITATION:
- /* it's a xtraz invitation to session */
- NetLog_Uni(bThruDC, "Received %s from %u", "Xtraz Invitation", dwUin);
- handleXtrazInvitation(dwUin, szMsg, bThruDC);
- break;
-
- case MTYPE_SCRIPT_DATA:
- /* it's a xtraz data packet */
- NetLog_Uni(bThruDC, "Received %s from %u", "Xtraz data packet", dwUin);
- handleXtrazData(dwUin, szMsg, bThruDC);
- break;
-
- case MTYPE_AUTOONLINE:
- case MTYPE_AUTOAWAY:
- case MTYPE_AUTOBUSY:
- case MTYPE_AUTONA:
- case MTYPE_AUTODND:
- case MTYPE_AUTOFFC:
- {
- char **szMsgs = MirandaStatusToAwayMsg(AwayMsgTypeToStatus(type));
- if (szMsgs) {
- struct rates_status_message_response : public rates_queue_item
- {
- protected:
- virtual rates_queue_item* copyItem(rates_queue_item *aDest = nullptr)
- {
- rates_status_message_response *pDest = (rates_status_message_response*)aDest;
- if (!pDest)
- pDest = new rates_status_message_response(ppro, wGroup);
-
- pDest->bExtended = bExtended;
- pDest->dwMsgID1 = dwMsgID1;
- pDest->dwMsgID2 = dwMsgID2;
- pDest->wCookie = wCookie;
- pDest->wVersion = wVersion;
- pDest->nMsgType = nMsgType;
-
- return rates_queue_item::copyItem(pDest);
- };
- public:
- rates_status_message_response(CIcqProto *ppro, WORD wGroup) : rates_queue_item(ppro, wGroup) {};
- virtual ~rates_status_message_response() {};
-
- virtual void execute()
- {
- char **pszMsg = ppro->MirandaStatusToAwayMsg(AwayMsgTypeToStatus(nMsgType));
- if (bExtended)
- ppro->icq_sendAwayMsgReplyServExt(dwUin, szUid, dwMsgID1, dwMsgID2, wCookie, wVersion, nMsgType, pszMsg);
- else if (dwUin)
- ppro->icq_sendAwayMsgReplyServ(dwUin, dwMsgID1, dwMsgID2, wCookie, wVersion, (BYTE)nMsgType, pszMsg);
- else
- ppro->debugLogA("Error: Malformed UIN in packet");
- };
-
- BOOL bExtended;
- DWORD dwMsgID1;
- DWORD dwMsgID2;
- WORD wCookie;
- WORD wVersion;
- int nMsgType;
- };
-
- WORD wGroup;
- {
- mir_cslock l(m_ratesMutex);
- wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE);
- }
-
- rates_status_message_response rr(this, wGroup);
- rr.bExtended = (nMsgFlags & MTF_STATUS_EXTENDED) == MTF_STATUS_EXTENDED;
- rr.hContact = hContact;
- rr.dwUin = dwUin;
- rr.szUid = szUID;
- rr.dwMsgID1 = dwMsgID;
- rr.dwMsgID2 = dwMsgID2;
- rr.wCookie = wCookie;
- rr.wVersion = wVersion;
- rr.nMsgType = type;
-
- handleRateItem(&rr, RQT_RESPONSE);
- }
- }
- break;
-
- case MTYPE_FILEREQ: // Never happens
- default:
- NetLog_Uni(bThruDC, "Unprocessed message type %d", type);
- break;
-
- }
-
- SAFE_FREE(&szMsg);
-}
-
-void CIcqProto::handleRecvMsgResponse(BYTE *buf, size_t wLen)
-{
- DWORD dwCookie;
- WORD wMessageFormat;
- WORD wStatus;
- WORD bMsgType = 0;
- BYTE bFlags;
- WORD wLength;
- WORD wVersion = 0;
- cookie_message_data *pCookieData = nullptr;
-
- DWORD dwMsgID1, dwMsgID2;
- unpackLEDWord(&buf, &dwMsgID1); // Message ID
- unpackLEDWord(&buf, &dwMsgID2);
- wLen -= 8;
-
- unpackWord(&buf, &wMessageFormat);
- wLen -= 2;
- if (wMessageFormat != 2) {
- debugLogA("SNAC(4.B) Unknown type");
- return;
- }
-
- DWORD dwUin;
- uid_str szUid;
- if (!unpackUID(&buf, &wLen, &dwUin, &szUid))
- return;
-
- MCONTACT hContact = HContactFromUID(dwUin, szUid, nullptr);
-
- buf += 2; // 3. unknown
- wLen -= 2;
-
- MCONTACT hCookieContact;
- if (!FindMessageCookie(dwMsgID1, dwMsgID2, &dwCookie, &hCookieContact, &pCookieData)) {
- debugLogA("SNAC(4.B) Received an ack that I did not ask for from (%u)", dwUin);
- return;
- }
-
- if (IsValidOscarTransfer((basic_filetransfer*)pCookieData)) {
- // it is OFT response
- handleRecvServResponseOFT(buf, wLen, dwUin, szUid, pCookieData);
- return;
- }
-
- if (!dwUin) {
- // AIM cannot send this - just sanity
- debugLogA("Error: Invalid UID in message response.");
- return;
- }
-
- // Length of sub chunk?
- if (wLen >= 2) {
- unpackLEWord(&buf, &wLength);
- wLen -= 2;
- }
- else wLength = 0;
-
- if (wLength == 0x1b && pCookieData->bMessageType != MTYPE_REVERSE_REQUEST) {
- // this can be v8 greeting message reply
- unpackLEWord(&buf, &wVersion);
- buf += 27; /* unknowns from the msg we sent */
- wLen -= 29;
-
- // Message sequence (SEQ2)
- WORD wCookie;
- unpackLEWord(&buf, &wCookie);
- wLen -= 2;
-
- // Unknown (12 bytes)
- buf += 12;
- wLen -= 12;
-
- // Message type
- unpackByte(&buf, (BYTE*)&bMsgType);
- unpackByte(&buf, &bFlags);
- wLen -= 2;
-
- // Status
- unpackLEWord(&buf, &wStatus);
- wLen -= 2;
-
- // Priority?
- buf += 2;
- wLen -= 2;
-
- if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData)) {
- // use old reliable method
- debugLogA("Warning: Invalid cookie in %s from (%u)", "message response", dwUin);
-
- if (pCookieData->bMessageType != MTYPE_AUTOAWAY && bFlags == 3) { // most probably a broken ack of some kind (e.g. from R&Q), try to fix that
- bMsgType = pCookieData->bMessageType;
- bFlags = 0;
-
- debugLogA("Warning: Invalid message type in %s from (%u)", "message response", dwUin);
- }
- }
- else if (bMsgType != MTYPE_PLUGIN && pCookieData->bMessageType != MTYPE_AUTOAWAY) {
- // just because some clients break it...
- dwCookie = wCookie;
-
- if (bMsgType != pCookieData->bMessageType)
- debugLogA("Warning: Invalid message type in %s from (%u)", "message response", dwUin);
-
- bMsgType = pCookieData->bMessageType;
- }
- else if (pCookieData->bMessageType == MTYPE_AUTOAWAY && bMsgType != MTYPE_PLUGIN) {
- if (bMsgType != pCookieData->nAckType)
- debugLogA("Warning: Invalid message type in %s from (%u)", "message response", dwUin);
- }
- }
- else {
- bMsgType = pCookieData->bMessageType;
- bFlags = 0;
- wStatus = 0;
- }
-
- if (hCookieContact != hContact) {
- debugLogA("SNAC(4.B) Ack Contact does not match Cookie Contact(0x%x != 0x%x)", hContact, hCookieContact);
- ReleaseCookie(dwCookie); // This could be a bad idea, but I think it is safe
- return;
- }
-
- if (bFlags == 3) // A status message reply
- handleStatusMsgReply("SNAC(4.B) ", hContact, dwUin, bMsgType, dwCookie, (char*)(buf + 2));
- else {
- // An ack of some kind
- int ackType;
-
- if (hContact == NULL || hContact == INVALID_CONTACT_ID) {
- debugLogA("SNAC(4.B) Message from unknown contact (%u)", dwUin);
- ReleaseCookie(dwCookie); // This could be a bad idea, but I think it is safe
- return;
- }
-
- WORD wMsgLen;
- switch (bMsgType) {
- case MTYPE_FILEREQ:
- // Message length
- unpackLEWord(&buf, &wMsgLen);
- wLen -= 2;
- {
- char *szMsg = (char *)_alloca(wMsgLen + 1);
- szMsg[wMsgLen] = '\0';
- if (wMsgLen > 0) {
- memcpy(szMsg, buf, wMsgLen);
- buf += wMsgLen;
- wLen -= wMsgLen;
- }
- handleFileAck(buf, wLen, dwUin, dwCookie, wStatus);
- // No success protoack will be sent here, since all file requests
- // will have been 'sent' when the server returns its ack
- }
- return;
-
- case MTYPE_PLUGIN:
- if (wLength != 0x1B) {
- debugLogA("Invalid Greeting %s", "message response");
-
- ReleaseCookie(dwCookie);
- return;
- }
-
- debugLogA("Parsing Greeting %s", "message response");
-
- // Message
- unpackLEWord(&buf, &wMsgLen);
- wLen -= 2;
- buf += wMsgLen;
- wLen -= wMsgLen;
-
- // This packet is malformed. Possibly a file accept from Miranda IM 0.1.2.1
- if (wLen < 20) {
- ReleaseCookie(dwCookie);
- return;
- }
- {
- WORD wFunctionId;
- int typeId;
- if (!unpackPluginTypeId(&buf, &wLen, &typeId, &wFunctionId, FALSE)) {
- ReleaseCookie(dwCookie);
- return;
- }
-
- if (wLen < 4) {
- debugLogA("Error: Invalid greeting %s", "message response");
- ReleaseCookie(dwCookie);
- return;
- }
-
- // Length of remaining data
- DWORD dwLengthToEnd;
- unpackLEDWord(&buf, &dwLengthToEnd);
- wLen -= 4;
-
- DWORD dwDataLen;
- if (wLen >= 4 && dwLengthToEnd > 0)
- unpackLEDWord(&buf, &dwDataLen); // Length of message
- else
- dwDataLen = 0;
-
- switch (typeId) {
- case MTYPE_PLAIN:
- if (pCookieData && pCookieData->bMessageType == MTYPE_AUTOAWAY && dwLengthToEnd >= 4) {
- // ICQ 6 invented this
- char *szMsg = (char*)_alloca(dwDataLen + 1);
-
- if (dwDataLen > 0)
- memcpy(szMsg, buf, dwDataLen);
- szMsg[dwDataLen] = '\0';
- handleStatusMsgReply("SNAC(4.B) ", hContact, dwUin, pCookieData->nAckType, dwCookie, szMsg);
-
- ReleaseCookie(dwCookie);
- return;
- }
- ackType = ACKTYPE_MESSAGE;
- break;
-
- case MTYPE_URL:
- ackType = ACKTYPE_URL;
- break;
-
- case MTYPE_CONTACTS:
- ackType = ACKTYPE_CONTACTS;
- break;
-
- case MTYPE_FILEREQ:
- debugLogA("This is file ack");
- {
- char *szMsg = (char *)_alloca(dwDataLen + 1);
-
- if (dwDataLen > 0)
- memcpy(szMsg, buf, dwDataLen);
- szMsg[dwDataLen] = '\0';
- buf += dwDataLen;
- wLen -= dwDataLen;
-
- handleFileAck(buf, wLen, dwUin, dwCookie, wStatus);
- // No success protoack will be sent here, since all file requests
- // will have been 'sent' when the server returns its ack
- }
- return;
-
- case MTYPE_SCRIPT_NOTIFY:
- {
- char *szMsg = (char*)_alloca(dwDataLen + 1);
-
- if (dwDataLen > 0)
- memcpy(szMsg, buf, dwDataLen);
- szMsg[dwDataLen] = '\0';
-
- handleXtrazNotifyResponse(hContact, (WORD)dwCookie, szMsg);
-
- ReleaseCookie(dwCookie);
- }
- return;
-
- case MTYPE_STATUSMSGEXT:
- { // handle Away Message response (ICQ 6)
- char *szMsg = (char*)SAFE_MALLOC(dwDataLen + 1);
-
- if (dwDataLen > 0)
- memcpy(szMsg, buf, dwDataLen);
- szMsg[dwDataLen] = '\0';
- szMsg = EliminateHtml(szMsg, dwDataLen);
-
- handleStatusMsgReply("SNAC(4.B) ", hContact, dwUin, pCookieData->nAckType, (WORD)dwCookie, szMsg);
-
- SAFE_FREE(&szMsg);
-
- ReleaseCookie(dwCookie);
- }
- return;
-
- default:
- debugLogA("Error: Unknown plugin message response, type %d.", typeId);
- return;
- }
- }
- break;
-
- case MTYPE_PLAIN:
- ackType = ACKTYPE_MESSAGE;
- break;
-
- case MTYPE_URL:
- ackType = ACKTYPE_URL;
- break;
-
- case MTYPE_AUTHOK:
- case MTYPE_AUTHDENY:
- ackType = ACKTYPE_AUTHREQ;
- break;
-
- case MTYPE_ADDED:
- ackType = ACKTYPE_ADDED;
- break;
-
- case MTYPE_CONTACTS:
- ackType = ACKTYPE_CONTACTS;
- break;
-
- case MTYPE_REVERSE_REQUEST:
- {
- cookie_reverse_connect *pReverse = (cookie_reverse_connect*)pCookieData;
-
- if (pReverse->ft) {
- filetransfer *ft = (filetransfer*)pReverse->ft;
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
- }
- debugLogA("Reverse Connect request failed");
- // Set DC status to failed
- setByte(hContact, "DCStatus", 2);
-
- ReleaseCookie(dwCookie);
- }
- return;
-
- case MTYPE_CHAT:
- default:
- debugLogA("SNAC(4.B) Unknown message type (%u) in switch", bMsgType);
- return;
- }
-
- if ((ackType == MTYPE_PLAIN && pCookieData && (pCookieData->nAckType == ACKTYPE_CLIENT)) || ackType != MTYPE_PLAIN)
- ProtoBroadcastAck(hContact, ackType, ACKRESULT_SUCCESS, (HANDLE)(WORD)dwCookie, 0);
- }
-
- ReleaseCookie(dwCookie);
-}
-
-// A response to a CLI_SENDMSG
-void CIcqProto::handleRecvServMsgError(BYTE *buf, size_t wLen, DWORD dwSequence)
-{
- WORD wError;
- char *pszErrorMessage;
- MCONTACT hContact;
- cookie_message_data *pCookieData = nullptr;
- int nMessageType;
-
-
- if (wLen < 2)
- return;
-
- if (FindCookie((WORD)dwSequence, &hContact, (void**)&pCookieData)) {
- // all packet cookies from msg family has command 0 in the queue
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid)) {
- // Invalid contact
- FreeCookie((WORD)dwSequence);
- return;
- }
-
- // Error code
- unpackWord(&buf, &wError);
-
- if (wError == 9 && pCookieData->bMessageType == MTYPE_AUTOAWAY) {
- // we failed to request away message the normal way, try it AIM way
- icq_packet packet;
-
- serverPacketInit(&packet, 13 + getUINLen(dwUin));
- packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_REQ_USER_INFO, 0, (WORD)dwSequence);
- packWord(&packet, 0x03);
- packUIN(&packet, dwUin);
-
- sendServPacket(&packet);
- return;
- }
-
- // Not all of these are actually used in family 4
- // This will be moved into a special error handling function later
- switch (wError) {
- case 0x0002: // Server rate limit exceeded
- pszErrorMessage = Translate("You are sending too fast. Wait a while and try again.\r\nSNAC(4.1) Error x02");
- break;
-
- case 0x0003: // Client rate limit exceeded
- pszErrorMessage = Translate("You are sending too fast. Wait a while and try again.\r\nSNAC(4.1) Error x03");
- break;
-
- case 0x0004: // Recipient is not logged in (resend in a offline message)
- if (pCookieData->bMessageType == MTYPE_PLAIN) {
- if (pCookieData->isOffline) {
- // offline failed - most probably to AIM contact
- pszErrorMessage = Translate("The contact does not support receiving offline messages.");
- break;
- }
- // TODO: this needs better solution
- setWord(hContact, "Status", ID_STATUS_OFFLINE);
- }
- pszErrorMessage = Translate("The user has logged off. Select 'Retry' to send an offline message.\r\nSNAC(4.1) Error x04");
- break;
-
- case 0x0005: // Requested service unavailable
- pszErrorMessage = Translate("The messaging service is temporarily unavailable. Wait a while and try again.\r\nSNAC(4.1) Error x05");
- break;
-
- case 0x0009: // Not supported by client (resend in a simpler format)
- pszErrorMessage = Translate("The receiving client does not support this type of message.\r\nSNAC(4.1) Error x09");
- break;
-
- case 0x000A: // Refused by client
- pszErrorMessage = Translate("You sent too long message. The receiving client does not support it.\r\nSNAC(4.1) Error x0A");
- break;
-
- case 0x000E: // Incorrect SNAC format
- pszErrorMessage = Translate("The SNAC format was rejected by the server.\nSNAC(4.1) Error x0E");
- break;
-
- case 0x0013: // User temporarily unavailable
- pszErrorMessage = Translate("The user is temporarily unavailable. Wait a while and try again.\r\nSNAC(4.1) Error x13");
- break;
-
- case 0x0001: // Invalid SNAC header
- case 0x0006: // Requested service not defined
- case 0x0007: // You sent obsolete SNAC
- case 0x0008: // Not supported by server
- case 0x000B: // Reply too big
- case 0x000C: // Responses lost
- case 0x000D: // Request denied
- case 0x000F: // Insufficient rights
- case 0x0010: // In local permit/deny (recipient blocked)
- case 0x0011: // Sender too evil
- case 0x0012: // Receiver too evil
- case 0x0014: // No match
- case 0x0015: // List overflow
- case 0x0016: // Request ambiguous
- case 0x0017: // Server queue full
- case 0x0018: // Not while on AOL
- default:
- if (pszErrorMessage = (char*)_alloca(256))
- mir_snprintf(pszErrorMessage, 256, Translate("SNAC(4.1) SENDMSG Error (x%02x)"), wError);
- break;
- }
-
- switch (pCookieData->bMessageType) {
- case MTYPE_PLAIN:
- nMessageType = ACKTYPE_MESSAGE;
- break;
-
- case MTYPE_CHAT:
- nMessageType = ACKTYPE_CHAT;
- break;
-
- case MTYPE_FILEREQ:
- nMessageType = ACKTYPE_FILE;
- break;
-
- case MTYPE_URL:
- nMessageType = ACKTYPE_URL;
- break;
-
- case MTYPE_CONTACTS:
- nMessageType = ACKTYPE_CONTACTS;
- break;
-
- default:
- nMessageType = -1;
- break;
- }
-
- if (nMessageType != -1)
- ProtoBroadcastAck(hContact, nMessageType, ACKRESULT_FAILED, (HANDLE)(WORD)dwSequence, (LPARAM)pszErrorMessage);
- else
- debugLogA("Error: Message delivery to %u failed: %s", dwUin, pszErrorMessage);
-
- FreeCookie((WORD)dwSequence);
-
- if (pCookieData->bMessageType != MTYPE_FILEREQ)
- SAFE_FREE((void**)&pCookieData);
- }
- else {
- unpackWord(&buf, &wError);
- LogFamilyError(ICQ_MSG_FAMILY, wError);
- }
-}
-
-void CIcqProto::handleServerAck(BYTE *buf, size_t wLen, DWORD dwSequence)
-{
- DWORD dwUin;
- uid_str szUID;
- WORD wChannel;
- cookie_message_data *pCookieData;
-
- if (wLen < 13) {
- debugLogA("Ignoring SNAC(4,C) Packet to short");
- return;
- }
-
- buf += 8; // Skip first 8 bytes
- wLen -= 8;
-
- // Message channel
- unpackWord(&buf, &wChannel);
- wLen -= 2;
-
- // Sender
- if (!unpackUID(&buf, &wLen, &dwUin, &szUID)) return;
-
- MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr);
-
- if (FindCookie((WORD)dwSequence, nullptr, (void**)&pCookieData)) {
- // If the user requested a full ack, the
- // server ack should be ignored here.
- if (pCookieData && (pCookieData->nAckType == ACKTYPE_SERVER)) {
- if ((hContact != NULL) && (hContact != INVALID_CONTACT_ID)) {
- int ackType;
- int ackRes = ACKRESULT_SUCCESS;
-
- switch (pCookieData->bMessageType) {
- case MTYPE_PLAIN:
- ackType = ACKTYPE_MESSAGE;
- break;
-
- case MTYPE_CONTACTS:
- ackType = ACKTYPE_CONTACTS;
- break;
-
- case MTYPE_URL:
- ackType = ACKTYPE_URL;
- break;
-
- case MTYPE_FILEREQ:
- ackType = ACKTYPE_FILE;
- ackRes = ACKRESULT_SENTREQUEST;
- // Note 1: We are not allowed to free the cookie here because it
- // contains the filetransfer struct that we will need later
- // Note 2: The cookiedata is NOT a message_cookie_data*, it is a
- // filetransfer*. IMPORTANT! (it's one of those silly things)
- break;
-
- default:
- ackType = -1;
- debugLogA("Error: Unknown message type %d in ack", pCookieData->bMessageType);
- break;
- }
- if (ackType != -1)
- ProtoBroadcastAck(hContact, ackType, ackRes, (HANDLE)(WORD)dwSequence, 0);
-
- if (pCookieData->bMessageType != MTYPE_FILEREQ)
- SAFE_FREE((void**)&pCookieData); // this could be a bad idea, but I think it is safe
- }
- FreeCookie((WORD)dwSequence);
- }
- else if (pCookieData && (pCookieData->nAckType == ACKTYPE_CLIENT))
- debugLogA("Received a server ack, waiting for client ack.");
- else
- debugLogA("Ignored a server ack I did not ask for");
- }
-}
-
-void CIcqProto::handleMissedMsg(BYTE *buf, size_t wLen)
-{
- DWORD dwUin;
- uid_str szUid;
- WORD wChannel;
- WORD wWarningLevel;
- WORD wCount;
- WORD wError;
- WORD wTLVCount;
-
- if (wLen < 14)
- return; // Too short
-
- // Message channel?
- unpackWord(&buf, &wChannel);
- wLen -= 2;
-
- // Sender
- if (!unpackUID(&buf, &wLen, &dwUin, &szUid)) return;
-
- if (wLen < 8)
- return; // Too short
-
- // Warning level?
- unpackWord(&buf, &wWarningLevel);
- wLen -= 2;
-
- // TLV count
- unpackWord(&buf, &wTLVCount);
- wLen -= 2;
-
- // Read past user info TLVs
- oscar_tlv_chain *pChain = readIntoTLVChain(&buf, wLen - 4, wTLVCount);
- if (pChain)
- disposeChain(&pChain);
-
- if (wLen < 4)
- return; // Too short
-
- // Number of missed messages
- unpackWord(&buf, &wCount);
- wLen -= 2;
-
- // Error code
- unpackWord(&buf, &wError);
- wLen -= 2;
-
- { // offline retrieval process in progress, note that we received missed message notification
- cookie_offline_messages *cookie;
-
- if (FindCookieByType(CKT_OFFLINEMESSAGE, nullptr, nullptr, (void**)&cookie))
- cookie->nMissed++;
- }
-
- switch (wError) {
-
- case 0: // The message was invalid
- case 1: // The message was too long
- case 2: // The sender has flooded the server
- case 4: // You are too evil
- break;
-
- default:
- // 3 = Sender too evil (sender warn level > your max_msg_sevil)
- return;
- break;
- }
-
- // Create event to notify user
- int bAdded;
-
- AddEvent(HContactFromUID(dwUin, szUid, &bAdded), ICQEVENTTYPE_MISSEDMESSAGE, time(0), 0, sizeof(wError), (PBYTE)&wError);
-}
-
-void CIcqProto::handleOffineMessagesReply(DWORD dwRef)
-{
- cookie_offline_messages *cookie;
-
- if (FindCookie(dwRef, nullptr, (void**)&cookie)) {
- debugLogA("End of offline msgs, %u received", cookie->nMessages);
- if (cookie->nMissed) { // NASTY WORKAROUND!!
- // The ICQ server has a bug that causes offline messages to be received again and again when some
- // missed message notification is present (most probably it is not processed correctly and causes
- // the server to fail the purging process); try to purge them using the old offline messages
- // protocol. 2008/05/21
- debugLogA("Warning: Received %u missed message notifications, trying to fix the server.", cookie->nMissed);
-
- icq_packet packet;
- // This will delete the messages stored on server
- serverPacketInit(&packet, 24);
- packFNACHeader(&packet, ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST);
- packWord(&packet, 1); // TLV Type
- packWord(&packet, 10); // TLV Length
- packLEWord(&packet, 8); // Data length
- packLEDWord(&packet, m_dwLocalUIN); // My UIN
- packLEWord(&packet, CLI_DELETE_OFFLINE_MSGS_REQ); // Ack offline msgs
- packLEWord(&packet, 0x0000); // Request sequence number (we dont use this for now)
-
- // Send it
- sendServPacket(&packet);
- }
-
- ReleaseCookie(dwRef);
- }
- else debugLogA("Error: Received unexpected end of offline msgs.");
-}
-
-void CIcqProto::handleTypingNotification(BYTE *buf, size_t wLen)
-{
- if (wLen < 14) {
- debugLogA("Ignoring SNAC(4.x11) Packet to short");
- return;
- }
-
- // The message ID, unused?
- buf += 8;
- wLen -= 8;
-
- // Message channel, unused?
- WORD wChannel;
- unpackWord(&buf, &wChannel);
- wLen -= 2;
-
- // Sender
- DWORD dwUin;
- uid_str szUid;
- if (!unpackUID(&buf, &wLen, &dwUin, &szUid))
- return;
-
- MCONTACT hContact = HContactFromUID(dwUin, szUid, nullptr);
-
- if (hContact == INVALID_CONTACT_ID) return;
-
- // Typing notification code
- WORD wNotification;
- unpackWord(&buf, &wNotification);
- wLen -= 2;
-
- SetContactCapabilities(hContact, CAPF_TYPING);
-
- // Notify user
- switch (wNotification) {
- case MTN_FINISHED:
- case MTN_TYPED:
- CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_OFF);
- debugLogA("%s has stopped typing (ch %u).", strUID(dwUin, szUid), wChannel);
- break;
-
- case MTN_BEGUN:
- CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)60);
- debugLogA("%s is typing a message (ch %u).", strUID(dwUin, szUid), wChannel);
- break;
-
- case MTN_WINDOW_CLOSED:
- {
- char szFormat[MAX_PATH];
- char szMsg[MAX_PATH];
- char *nick = NickFromHandleUtf(hContact);
-
- mir_snprintf(szMsg, ICQTranslateUtfStatic(LPGEN("Contact \"%s\" has closed the message window."), szFormat, MAX_PATH), nick);
- ShowPopupMsg(hContact, ICQTranslateUtfStatic(LPGEN("ICQ Note"), szFormat, MAX_PATH), szMsg, LOG_NOTE);
- SAFE_FREE((void**)&nick);
-
- debugLogA("%s has closed the message window.", strUID(dwUin, szUid));
- }
- break;
-
- default:
- debugLogA("Unknown typing notification from %s, type %u (ch %u)", strUID(dwUin, szUid), wNotification, wChannel);
- break;
- }
-}
-
-void CIcqProto::sendTypingNotification(MCONTACT hContact, WORD wMTNCode)
-{
- _ASSERTE((wMTNCode == MTN_FINISHED) || (wMTNCode == MTN_TYPED) || (wMTNCode == MTN_BEGUN) || (wMTNCode == MTN_WINDOW_CLOSED));
-
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return; // Invalid contact
-
- size_t wLen = getUIDLen(dwUin, szUid);
-
- icq_packet packet;
- serverPacketInit(&packet, 23 + wLen);
- packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_MTN);
- packLEDWord(&packet, 0x0000); // Msg ID
- packLEDWord(&packet, 0x0000); // Msg ID
- packWord(&packet, 0x01); // Channel
- packUID(&packet, dwUin, szUid); // User ID
- packWord(&packet, wMTNCode); // Notification type
-
- sendServPacketAsync(&packet);
-}
diff --git a/protocols/IcqOscarJ/src/fam_09bos.cpp b/protocols/IcqOscarJ/src/fam_09bos.cpp
deleted file mode 100644
index 53cefff9b8..0000000000
--- a/protocols/IcqOscarJ/src/fam_09bos.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleBosFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader)
-{
- switch (pSnacHeader->wSubtype) {
- case ICQ_PRIVACY_RIGHTS_REPLY: // Reply to CLI_REQBOS
- handlePrivacyRightsReply(pBuffer, wBufferLength);
- break;
-
- case ICQ_ERROR:
- {
- WORD wError;
-
- if (wBufferLength >= 2)
- unpackWord(&pBuffer, &wError);
- else
- wError = 0;
-
- LogFamilyError(ICQ_BOS_FAMILY, wError);
- break;
- }
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_BOS_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-void CIcqProto::handlePrivacyRightsReply(unsigned char *pBuffer, size_t wBufferLength)
-{
- if (wBufferLength >= 12) {
- oscar_tlv_chain* pChain = readIntoTLVChain(&pBuffer, wBufferLength, 0);
- if (pChain) {
- WORD wMaxVisibleContacts = pChain->getWord(0x0001, 1);
- WORD wMaxInvisibleContacts = pChain->getWord(0x0002, 1);
- WORD wMaxTemporaryVisibleContacts = pChain->getWord(0x0003, 1);
-
- disposeChain(&pChain);
-
- debugLogA("PRIVACY: Max visible %u, max invisible %u, max temporary visible %u items.", wMaxVisibleContacts, wMaxInvisibleContacts, wMaxTemporaryVisibleContacts);
-
- // Success
- return;
- }
- }
-
- // Failure
- debugLogA("Warning: Malformed SRV_PRIVACY_RIGHTS_REPLY");
-}
-
-void CIcqProto::makeContactTemporaryVisible(MCONTACT hContact)
-{
- if (getByte(hContact, "TemporaryVisible", 0))
- return; // already there
-
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return; // Invalid contact
-
- icq_sendGenericContact(dwUin, szUid, ICQ_BOS_FAMILY, ICQ_CLI_ADDTEMPVISIBLE);
-
- setByte(hContact, "TemporaryVisible", 1);
-
- debugLogA("Added contact %s to temporary visible list", strUID(dwUin, szUid));
-}
diff --git a/protocols/IcqOscarJ/src/fam_0alookup.cpp b/protocols/IcqOscarJ/src/fam_0alookup.cpp
deleted file mode 100644
index cdce8c145b..0000000000
--- a/protocols/IcqOscarJ/src/fam_0alookup.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleLookupFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader)
-{
- switch (pSnacHeader->wSubtype) {
-
- case ICQ_LOOKUP_EMAIL_REPLY: // AIM search reply
- handleLookupEmailReply(pBuffer, wBufferLength, pSnacHeader->dwRef);
- break;
-
- case ICQ_ERROR:
- {
- WORD wError;
- if (wBufferLength >= 2)
- unpackWord(&pBuffer, &wError);
- else
- wError = 0;
-
- cookie_search *pCookie;
- if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookie)) {
- if (wError == 0x14)
- debugLogA("Lookup: No results");
-
- ReleaseLookupCookie(pSnacHeader->dwRef, pCookie);
-
- if (wError == 0x14) return;
- }
-
- LogFamilyError(ICQ_LOOKUP_FAMILY, wError);
- }
- break;
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_LOOKUP_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-void CIcqProto::ReleaseLookupCookie(DWORD dwCookie, cookie_search *pCookie)
-{
- FreeCookie(dwCookie);
- SAFE_FREE(&pCookie->szObject);
-
- if (pCookie->dwMainId && !pCookie->dwStatus) // we need to wait for main search
- pCookie->dwStatus = 1;
- else { // finish everything
- if (pCookie->dwMainId)
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)pCookie->dwMainId, 0);
- else // we are single
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0);
-
- SAFE_FREE((void**)&pCookie);
- }
-}
-
-void CIcqProto::handleLookupEmailReply(BYTE* buf, size_t wLen, DWORD dwCookie)
-{
- ICQSEARCHRESULT sr = { 0 };
- oscar_tlv_chain *pChain;
- cookie_search *pCookie;
-
- if (!FindCookie(dwCookie, nullptr, (void**)&pCookie)) {
- debugLogA("Error: Received unexpected lookup reply");
- return;
- }
-
- debugLogA("SNAC(0x0A,0x3): Lookup reply");
-
- sr.hdr.cbSize = sizeof(sr);
- sr.hdr.flags = PSR_UNICODE;
- sr.hdr.email.w = ansi_to_unicode(pCookie->szObject);
-
- // Syntax check, read chain
- if (wLen >= 4 && (pChain = readIntoTLVChain(&buf, wLen, 0))) {
- for (WORD i = 1; TRUE; i++) { // collect the results
- char *szUid = pChain->getString(0x01, i);
- if (!szUid) break;
- sr.hdr.id.w = ansi_to_unicode(szUid);
- sr.hdr.nick.w = sr.hdr.id.w;
- // broadcast the result
- if (pCookie->dwMainId)
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)pCookie->dwMainId, (LPARAM)&sr);
- else
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)dwCookie, (LPARAM)&sr);
- SAFE_FREE(&sr.hdr.id.w);
- SAFE_FREE(&szUid);
- }
- disposeChain(&pChain);
- }
- SAFE_FREE(&sr.hdr.email.w);
-
- ReleaseLookupCookie(dwCookie, pCookie);
-}
diff --git a/protocols/IcqOscarJ/src/fam_0bstatus.cpp b/protocols/IcqOscarJ/src/fam_0bstatus.cpp
deleted file mode 100644
index 6f7b5d69d3..0000000000
--- a/protocols/IcqOscarJ/src/fam_0bstatus.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001,2002 Jon Keating, Richard Hughes
-// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004,2005,2006 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleStatusFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader)
-{
- switch (pSnacHeader->wSubtype) {
-
- case ICQ_STATS_MINREPORTINTERVAL:
- WORD wInterval;
- unpackWord(&pBuffer, &wInterval);
- debugLogA("Server sent SNAC(x0B,x02) - SRV_SET_MINREPORTINTERVAL (Value: %u hours)", wInterval);
- break;
-
- case ICQ_ERROR:
- WORD wError;
- if (wBufferLength >= 2)
- unpackWord(&pBuffer, &wError);
- else
- wError = 0;
-
- LogFamilyError(ICQ_STATS_FAMILY, wError);
- break;
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_STATS_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
diff --git a/protocols/IcqOscarJ/src/fam_13servclist.cpp b/protocols/IcqOscarJ/src/fam_13servclist.cpp
deleted file mode 100644
index c3dcf0a02d..0000000000
--- a/protocols/IcqOscarJ/src/fam_13servclist.cpp
+++ /dev/null
@@ -1,1720 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-static int unpackServerListItem(BYTE **pbuf, size_t *pwLen, char *pszRecordName, WORD *pwGroupId, WORD *pwItemId, WORD *pwItemType, size_t *pwTlvLength);
-
-void CIcqProto::handleServCListFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader, serverthread_info *info)
-{
- switch (pSnacHeader->wSubtype) {
- case ICQ_LISTS_ACK: // UPDATE_ACK
- if (wBufferLength >= 2) {
- WORD wError;
- unpackWord(&pBuffer, &wError);
-
- cookie_servlist_action *sc;
- if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&sc)) { // look for action cookie
- debugLogA("Received expected server list ack, action: %d, result: %d", sc->dwAction, wError);
- FreeCookie(pSnacHeader->dwRef); // release cookie
-
- if (sc->dwAction == SSA_ACTION_GROUP) { // group cookie, handle sub-items
- int i;
-
- debugLogA("Server-List: Grouped action contains %d actions.", sc->dwGroupCount);
-
- pBuffer -= 2; // revoke unpack
- if ((int)wBufferLength != 2 * sc->dwGroupCount)
- debugLogA("Error: Server list ack does not contain expected amount of result codes (%u != %u)", wBufferLength / 2, sc->dwGroupCount);
-
- for (i = 0; i < sc->dwGroupCount; i++) {
- if (wBufferLength >= 2) { // get proper result code
- unpackWord(&pBuffer, &wError);
- wBufferLength -= 2;
- }
- else // missing result code, give some special
- wError = -1;
-
- debugLogA("Action: %d, ack result: %d", sc->pGroupItems[i]->dwAction, wError);
-
- // call normal ack handler
- handleServerCListAck(sc->pGroupItems[i], wError);
- }
- // Release cookie
- SAFE_FREE((void**)&sc->pGroupItems);
- SAFE_FREE((void**)&sc);
- }
- else // single ack
- handleServerCListAck(sc, wError);
- }
- else debugLogA("Received unexpected server list ack %u", wError);
- }
- break;
-
- case ICQ_LISTS_SRV_REPLYLISTS:
- /* received server-list rights */
- handleServerCListRightsReply(pBuffer, wBufferLength);
- debugLogA("Server sent SNAC(x13,x03) - SRV_REPLYLISTS");
- break;
-
- case ICQ_LISTS_LIST: // SRV_REPLYROSTER
- {
- cookie_servlist_action* sc;
- BOOL blWork = bIsSyncingCL;
- bIsSyncingCL = TRUE; // this is not used if cookie takes place
-
- if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&sc)) { // we do it by reliable cookie
- if (!sc->lParam) { // is this first packet ?
- ResetSettingsOnListReload();
- sc->lParam = 1;
- }
- handleServerCListReply(pBuffer, wBufferLength, pSnacHeader->wFlags, info);
- if (!(pSnacHeader->wFlags & 0x0001)) // was that last packet ?
- ReleaseCookie(pSnacHeader->dwRef); // yes, release cookie
- }
- else { // use old fake
- if (!blWork) // this can fail on some crazy situations
- ResetSettingsOnListReload();
-
- handleServerCListReply(pBuffer, wBufferLength, pSnacHeader->wFlags, info);
- }
- }
- break;
-
- case ICQ_LISTS_UPTODATE: // SRV_REPLYROSTEROK
- bIsSyncingCL = FALSE;
- {
- cookie_servlist_action* sc;
- if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&sc)) { // we requested servlist check
- debugLogA("Server stated roster is ok.");
- ReleaseCookie(pSnacHeader->dwRef);
- LoadServerIDs();
- }
- else debugLogA("Server sent unexpected SNAC(x13,x0F) - SRV_REPLYROSTEROK");
-
- // This will activate the server side list
- sendRosterAck(); // this must be here, cause of failures during cookie alloc
- handleServUINSettings(wListenPort, info);
- }
- break;
-
- case ICQ_LISTS_CLI_MODIFYSTART:
- debugLogA("Server sent SNAC(x13,x%02x) - %s", ICQ_LISTS_CLI_MODIFYSTART, "Server is modifying contact list");
- break;
-
- case ICQ_LISTS_CLI_MODIFYEND:
- debugLogA("Server sent SNAC(x13,x%02x) - %s", ICQ_LISTS_CLI_MODIFYEND, "End of server modification");
- break;
-
- case ICQ_LISTS_ADDTOLIST:
- case ICQ_LISTS_UPDATEGROUP:
- case ICQ_LISTS_REMOVEFROMLIST:
- {
- int nItems = 0;
-
- while (wBufferLength >= 10) {
- WORD wGroupId, wItemId, wItemType;
- size_t wTlvLen;
- uid_str szRecordName;
-
- if (unpackServerListItem(&pBuffer, &wBufferLength, szRecordName, &wGroupId, &wItemId, &wItemType, &wTlvLen)) {
- BYTE *buf = pBuffer;
- oscar_tlv_chain *pChain = nullptr;
-
- nItems++;
-
- // parse possible item's data
- if (wBufferLength >= wTlvLen && wTlvLen > 0) {
- pChain = readIntoTLVChain(&buf, wTlvLen, 0);
- pBuffer += wTlvLen;
- wBufferLength -= wTlvLen;
- }
- else if (wTlvLen > 0)
- wBufferLength = 0;
-
- // process item change
- if (pSnacHeader->wSubtype == ICQ_LISTS_ADDTOLIST)
- handleServerCListItemAdd(wItemId, wItemType, pChain);
- else if (pSnacHeader->wSubtype == ICQ_LISTS_UPDATEGROUP)
- handleServerCListItemUpdate(szRecordName, wItemType, pChain);
- else if (pSnacHeader->wSubtype == ICQ_LISTS_REMOVEFROMLIST)
- handleServerCListItemDelete(szRecordName, wItemId, wItemType);
-
- // release memory
- disposeChain(&pChain);
- }
- }
-
- // log packet basics
- char *szChange;
-
- if (pSnacHeader->wSubtype == ICQ_LISTS_ADDTOLIST)
- szChange = "Server added %u item(s) to list";
- else if (pSnacHeader->wSubtype == ICQ_LISTS_UPDATEGROUP)
- szChange = "Server updated %u item(s) on list";
- else if (pSnacHeader->wSubtype == ICQ_LISTS_REMOVEFROMLIST)
- szChange = "Server removed %u item(s) from list";
- else
- break;
-
- char szLogText[MAX_PATH];
- mir_snprintf(szLogText, szChange, nItems);
- debugLogA("Server sent SNAC(x13,x%02x) - %s", pSnacHeader->wSubtype, szLogText);
- }
- break;
-
- case ICQ_LISTS_AUTHREQUEST:
- handleRecvAuthRequest(pBuffer, wBufferLength);
- break;
-
- case ICQ_LISTS_SRV_AUTHRESPONSE:
- handleRecvAuthResponse(pBuffer, wBufferLength);
- break;
-
- case ICQ_LISTS_AUTHGRANTED:
- debugLogA("Server sent SNAC(x13,x%02x) - %s", ICQ_LISTS_AUTHGRANTED, "User granted us future authorization");
- break;
-
- case ICQ_LISTS_YOUWEREADDED:
- handleRecvAdded(pBuffer, wBufferLength);
- break;
-
- case ICQ_LISTS_ERROR:
- if (wBufferLength >= 2) {
- WORD wError;
- cookie_servlist_action* sc;
-
- unpackWord(&pBuffer, &wError);
-
- if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&sc)) { // look for action cookie
- debugLogA("Received server list error, action: %d, result: %d", sc->dwAction, wError);
- FreeCookie(pSnacHeader->dwRef); // release cookie
-
- if (sc->dwAction == SSA_CHECK_ROSTER) { // the serv-list is unavailable turn it off
- icq_LogMessage(LOG_ERROR, LPGEN("Server contact list is unavailable, Miranda will use local contact list."));
- m_bSsiEnabled = 0;
- handleServUINSettings(wListenPort, info);
- }
- /// FIXME: properly release pending operations & cookie memory
- SAFE_FREE((void**)&sc);
- }
- else LogFamilyError(ICQ_LISTS_FAMILY, wError);
- }
- break;
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_LISTS_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-
-static int unpackServerListItem(BYTE **pbuf, size_t *pwLen, char *pszRecordName, WORD *pwGroupId, WORD *pwItemId, WORD *pwItemType, size_t *pwTlvLength)
-{
- size_t wRecordNameLen;
-
- // The name of the entry. If this is a group header, then this
- // is the name of the group. If it is a plain contact list entry,
- // then it's the UIN of the contact.
- unpackWord(pbuf, &wRecordNameLen);
- if (*pwLen < 10 + wRecordNameLen || wRecordNameLen >= MAX_PATH)
- return 0; // Failure
-
- unpackString(pbuf, pszRecordName, wRecordNameLen);
- if (pszRecordName)
- pszRecordName[wRecordNameLen] = '\0';
-
- // The group identifier this entry belongs to. If 0, this is meta information or
- // a contact without a group
- unpackWord(pbuf, pwGroupId);
-
- // The ID of this entry. Group headers have ID 0. Otherwise, this
- // is a random number generated when the user is added to the
- // contact list, or when the user is ignored. See CLI_ADDBUDDY.
- unpackWord(pbuf, pwItemId);
-
- // This field indicates what type of entry this is
- unpackWord(pbuf, pwItemType);
-
- // The length in bytes of the following TLV chain
- unpackWord(pbuf, pwTlvLength);
-
- *pwLen -= wRecordNameLen + 10;
-
- return 1; // Success
-}
-
-
-void CIcqProto::handleServerCListRightsReply(BYTE *buf, size_t wLen)
-{
- /* received list rights, store the item limits for future use */
- oscar_tlv_chain* chain;
-
- memset(m_wServerListLimits, -1, sizeof(m_wServerListLimits));
- m_wServerListGroupMaxContacts = 0;
- m_wServerListRecordNameMaxLength = 0xFFFF;
-
- if (chain = readIntoTLVChain(&buf, wLen, 0)) {
- // determine max number of contacts in a group
- m_wServerListGroupMaxContacts = chain->getWord(0x0C, 1);
- // determine length limit for server-list item's name
- m_wServerListRecordNameMaxLength = chain->getWord(0x06, 1);
-
- if (oscar_tlv *pTLV = chain->getTLV(0x04, 1)) { // limits for item types
- WORD *pLimits = (WORD*)pTLV->pData;
- for (int i = 0; i < pTLV->wLen / 2; i++) {
- m_wServerListLimits[i] = (pLimits[i] & 0xFF) << 8 | (pLimits[i] >> 8);
-
- if (i + 1 >= _countof(m_wServerListLimits))
- break;
- }
-
- debugLogA("SSI: Max %d contacts (%d per group), %d groups, %d permit, %d deny, %d ignore items.", m_wServerListLimits[SSI_ITEM_BUDDY], m_wServerListGroupMaxContacts, m_wServerListLimits[SSI_ITEM_GROUP], m_wServerListLimits[SSI_ITEM_PERMIT], m_wServerListLimits[SSI_ITEM_DENY], m_wServerListLimits[SSI_ITEM_IGNORE]);
- }
-
- disposeChain(&chain);
- }
-}
-
-DWORD CIcqProto::updateServerGroupData(WORD wGroupId, void *groupData, int groupSize, DWORD dwOperationFlags)
-{
- cookie_servlist_action* ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (!ack) {
- debugLogA("Updating of group on server list failed (malloc error)");
- return 0;
- }
- ack->dwAction = SSA_GROUP_UPDATE;
- ack->szGroupName = getServListGroupName(wGroupId);
- ack->wGroupId = wGroupId;
-
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack);
- return icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, ack->wGroupId, ack->szGroupName, groupData, groupSize, dwOperationFlags);
-}
-
-void CIcqProto::handleServerCListAck(cookie_servlist_action* sc, WORD wError)
-{
- switch (sc->dwAction) {
- case SSA_VISIBILITY:
- if (wError)
- debugLogA("Server visibility update failed, error %d", wError);
- break;
-
- case SSA_CONTACT_UPDATE:
- servlistPendingRemoveContact(sc->hContact, sc->wContactId, sc->wGroupId, wError ? PENDING_RESULT_FAILED : PENDING_RESULT_SUCCESS);
- if (wError) {
- debugLogA("Updating of server contact failed, error %d", wError);
- icq_LogMessage(LOG_WARNING, LPGEN("Updating of server contact failed."));
- }
- break;
-
- case SSA_PRIVACY_ADD:
- if (wError) {
- debugLogA("Adding of privacy item to server list failed, error %d", wError);
- icq_LogMessage(LOG_WARNING, LPGEN("Adding of privacy item to server list failed."));
- }
- break;
-
- case SSA_PRIVACY_REMOVE:
- if (wError) {
- debugLogA("Removing of privacy item from server list failed, error %d", wError);
- icq_LogMessage(LOG_WARNING, LPGEN("Removing of privacy item from server list failed."));
- }
- FreeServerID(sc->wContactId, SSIT_ITEM); // release server id
- break;
-
- case SSA_CONTACT_ADD:
- if (wError) {
- if (wError == 0xE) { // server refused to add contact w/o auth, add with
- debugLogA("Contact could not be added without authorization, add with await auth flag.");
-
- setByte(sc->hContact, "Auth", 1); // we need auth
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, sc->hContact, sc);
- icq_sendServerContact(sc->hContact, dwCookie, ICQ_LISTS_ADDTOLIST, sc->wGroupId, sc->wContactId, SSOP_ITEM_ACTION | SSOF_CONTACT, 500, nullptr);
-
- sc = nullptr; // we do not want it to be freed now
- break;
- }
- FreeServerID(sc->wContactId, SSIT_ITEM);
-
- debugLogA("Adding of contact to server list failed, error %d", wError);
- icq_LogMessage(LOG_WARNING, LPGEN("Adding of contact to server list failed."));
-
- servlistPendingRemoveContact(sc->hContact, 0, sc->wGroupId, PENDING_RESULT_FAILED);
-
- servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here
- }
- else {
- void* groupData;
- int groupSize;
-
- setWord(sc->hContact, DBSETTING_SERVLIST_ID, sc->wContactId);
- setWord(sc->hContact, DBSETTING_SERVLIST_GROUP, sc->wGroupId);
-
- servlistPendingRemoveContact(sc->hContact, sc->wContactId, sc->wGroupId, PENDING_RESULT_SUCCESS);
-
- if (groupData = collectBuddyGroup(sc->wGroupId, &groupSize)) { // the group is not empty, just update it
- updateServerGroupData(sc->wGroupId, groupData, groupSize, SSOF_END_OPERATION);
- SAFE_FREE((void**)&groupData);
- }
- else { // this should never happen
- debugLogA("Group update failed.");
- servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here
- }
- }
- break;
-
- case SSA_GROUP_ADD:
- if (wError) {
- FreeServerID(sc->wGroupId, SSIT_GROUP);
- debugLogA("Adding of group to server list failed, error %d", wError);
- icq_LogMessage(LOG_WARNING, LPGEN("Adding of group to server list failed."));
-
- servlistPendingRemoveGroup(sc->szGroup, 0, PENDING_RESULT_FAILED);
- }
- else { // group added, we need to update master group
- void* groupData;
- int groupSize;
-
- setServListGroupName(sc->wGroupId, sc->szGroupName); // add group to namelist
- { // add group to known
- char *szCListGroup = getServListGroupCListPath(sc->wGroupId);
-
- // create link to the original CList group
- setServListGroupLinkID(sc->szGroup, sc->wGroupId);
-
- servlistPendingRemoveGroup(sc->szGroup, sc->wGroupId, PENDING_RESULT_SUCCESS);
- SAFE_FREE((void**)&szCListGroup);
- }
-
- groupData = collectGroups(&groupSize);
- groupData = SAFE_REALLOC(groupData, groupSize + 2);
- *(((WORD*)groupData) + (groupSize >> 1)) = sc->wGroupId; // add this new group id
- groupSize += 2;
-
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (ack) {
- ack->dwAction = SSA_GROUP_UPDATE;
-
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack);
- icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, 0, ack->szGroupName, groupData, groupSize, SSOF_END_OPERATION);
- }
- else // end server modifications here
- servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100);
-
- SAFE_FREE((void**)&groupData);
- }
- if (sc->szGroup != sc->szGroupName)
- SAFE_FREE((void**)&sc->szGroup);
-
- SAFE_FREE((void**)&sc->szGroupName);
- break;
-
- case SSA_CONTACT_REMOVE:
- if (!wError) {
- void* groupData;
- int groupSize;
-
- setWord(sc->hContact, DBSETTING_SERVLIST_ID, 0); // clear the values
- setWord(sc->hContact, DBSETTING_SERVLIST_GROUP, 0);
-
- FreeServerID(sc->wContactId, SSIT_ITEM);
-
- servlistPendingRemoveContact(sc->hContact, 0, sc->wGroupId, PENDING_RESULT_SUCCESS);
-
- if (groupData = collectBuddyGroup(sc->wGroupId, &groupSize)) { // the group is still not empty, just update it
- updateServerGroupData(sc->wGroupId, groupData, groupSize, SSOF_END_OPERATION);
- }
- else // the group is empty, delete it
- {
- char *szGroup = getServListGroupCListPath(sc->wGroupId);
-
- servlistRemoveGroup(szGroup, sc->wGroupId);
- SAFE_FREE((void**)&szGroup);
- }
- SAFE_FREE((void**)&groupData); // free the memory
- }
- else {
- debugLogA("Removing of contact from server list failed, error %d", wError);
- icq_LogMessage(LOG_WARNING, LPGEN("Removing of contact from server list failed."));
-
- servlistPendingRemoveContact(sc->hContact, sc->wContactId, sc->wGroupId, PENDING_RESULT_FAILED);
-
- servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here
- }
- break;
-
- case SSA_GROUP_UPDATE:
- if (wError) {
- debugLogA("Updating of group on server list failed, error %d", wError);
- icq_LogMessage(LOG_WARNING, LPGEN("Updating of group on server list failed."));
- }
- SAFE_FREE((void**)&sc->szGroupName);
- break;
-
- case SSA_GROUP_REMOVE:
- SAFE_FREE((void**)&sc->szGroupName);
- if (wError) {
- debugLogA("Removing of group from server list failed, error %d", wError);
- icq_LogMessage(LOG_WARNING, LPGEN("Removing of group from server list failed."));
-
- servlistPendingRemoveGroup(sc->szGroup, 0, PENDING_RESULT_FAILED);
-
- servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here
- SAFE_FREE((void**)&sc->szGroup);
- }
- else { // group removed, we need to update master group
- void* groupData;
- int groupSize;
-
- setServListGroupName(sc->wGroupId, nullptr); // clear group from namelist
- FreeServerID(sc->wGroupId, SSIT_GROUP);
- removeGroupPathLinks(sc->wGroupId);
-
- servlistPendingRemoveGroup(sc->szGroup, 0, PENDING_RESULT_SUCCESS);
- SAFE_FREE((void**)&sc->szGroup);
-
- groupData = collectGroups(&groupSize);
- sc->wGroupId = 0;
- sc->dwAction = SSA_GROUP_UPDATE;
- sc->szGroupName = nullptr;
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, sc);
-
- icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, 0, sc->szGroupName, groupData, groupSize, SSOF_END_OPERATION);
- // end server modifications here
-
- sc = nullptr; // we do not want to be freed here
-
- SAFE_FREE((void**)&groupData);
- }
- break;
-
- case SSA_CONTACT_SET_GROUP:
- // we moved contact to another group
- if (sc->lParam == -1) // the first was an error
- break;
-
- if (wError) {
- if (wError == 0x0E && sc->lParam == 1) { // second ack - adding failed with error 0x0E, try to add with AVAIT_AUTH flag
- if (!getByte(sc->hContact, "Auth", 0)) { // we tried without AWAIT_AUTH, try again with it
- debugLogA("Contact could not be added without authorization, add with await auth flag.");
- setByte(sc->hContact, "Auth", 1); // we need auth
- }
- else { // we tried with AWAIT_AUTH, try again without
- debugLogA("Contact count not be added awaiting authorization, try authorized.");
- setByte(sc->hContact, "Auth", 0);
- }
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, sc->hContact, sc);
- icq_sendServerContact(sc->hContact, dwCookie, ICQ_LISTS_ADDTOLIST, sc->wNewGroupId, sc->wNewContactId, SSOP_ITEM_ACTION | SSOF_CONTACT, 400, nullptr);
-
- sc->lParam = 2; // do not cycle
- sc = nullptr; // we do not want to be freed here
- break;
- }
- FreeServerID(sc->wNewContactId, SSIT_ITEM);
- debugLogA("Moving of user to another group on server list failed, error %d", wError);
- icq_LogMessage(LOG_ERROR, LPGEN("Moving of user to another group on server list failed."));
-
- servlistPendingRemoveContact(sc->hContact, 0, (WORD)(sc->lParam ? sc->wGroupId : sc->wNewGroupId), PENDING_RESULT_FAILED);
-
- servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here
-
- if (!sc->lParam) { // is this first ack ?
- sc->lParam = -1;
- sc = nullptr; // this can't be freed here
- }
- break;
- }
-
- if (sc->lParam) { // is this the second ack ?
- void* groupData;
- int groupSize;
- int bEnd = 1; // shall we end the sever modifications
-
- setWord(sc->hContact, DBSETTING_SERVLIST_ID, sc->wNewContactId);
- setWord(sc->hContact, DBSETTING_SERVLIST_GROUP, sc->wNewGroupId);
-
- servlistPendingRemoveContact(sc->hContact, sc->wNewContactId, sc->wNewGroupId, PENDING_RESULT_SUCCESS);
-
- if (groupData = collectBuddyGroup(sc->wGroupId, &groupSize)) // update the group we moved from
- { // the group is still not empty, just update it
- updateServerGroupData(sc->wGroupId, groupData, groupSize, 0);
- SAFE_FREE((void**)&groupData); // free the memory
- }
- else { // the group is empty, delete it
- char* szGroup = getServListGroupCListPath(sc->wGroupId);
-
- servlistRemoveGroup(szGroup, sc->wGroupId);
- SAFE_FREE((void**)&szGroup);
- bEnd = 0; // here the modifications go on
- }
-
- groupData = collectBuddyGroup(sc->wNewGroupId, &groupSize); // update the group we moved to
- updateServerGroupData(sc->wNewGroupId, groupData, groupSize, bEnd ? SSOF_END_OPERATION : 0);
- // end server modifications here
- SAFE_FREE((void**)&groupData);
-
- }
- else // contact was deleted from server-list
- {
- delSetting(sc->hContact, DBSETTING_SERVLIST_ID);
- delSetting(sc->hContact, DBSETTING_SERVLIST_GROUP);
- FreeServerID(sc->wContactId, SSIT_ITEM); // release old contact id
- sc->lParam = 1;
- sc = nullptr; // wait for second ack
- }
- break;
-
- case SSA_CONTACT_FIX_AUTH:
- if (wError) { // FIXME: something failed, we should handle it properly
- }
- break;
-
- case SSA_GROUP_RENAME:
- if (wError) {
- debugLogA("Renaming of server group failed, error %d", wError);
- icq_LogMessage(LOG_WARNING, LPGEN("Renaming of server group failed."));
-
- servlistPendingRemoveGroup(sc->szGroup, sc->wGroupId, PENDING_RESULT_FAILED);
- }
- else {
- setServListGroupName(sc->wGroupId, sc->szGroupName);
- removeGroupPathLinks(sc->wGroupId);
- { // add group to known
- char *szCListGroup = getServListGroupCListPath(sc->wGroupId);
-
- /// FIXME: need to create link to the new group name before unique item name correction as well
- setServListGroupLinkID(szCListGroup, sc->wGroupId);
- SAFE_FREE((void**)&szCListGroup);
- }
- servlistPendingRemoveGroup(sc->szGroup, sc->wGroupId, PENDING_RESULT_SUCCESS);
- }
- SAFE_FREE((void**)&sc->szGroupName);
- SAFE_FREE((void**)&sc->szGroup);
- break;
-
- case SSA_SETAVATAR:
- if (wError) {
- debugLogA("Uploading of avatar hash failed.");
- if (sc->wGroupId) { // is avatar added or updated?
- FreeServerID(sc->wContactId, SSIT_ITEM);
- delSetting(DBSETTING_SERVLIST_AVATAR); // to fix old versions
- }
- }
- else setWord(DBSETTING_SERVLIST_AVATAR, sc->wContactId);
- break;
-
- case SSA_REMOVEAVATAR:
- if (wError)
- debugLogA("Removing of avatar hash failed.");
- else {
- FreeServerID(sc->wContactId, SSIT_ITEM);
- delSetting(DBSETTING_SERVLIST_AVATAR);
- }
- break;
-
- case SSA_SERVLIST_ACK:
- ProtoBroadcastAck(sc->hContact, ICQACKTYPE_SERVERCLIST, wError ? ACKRESULT_FAILED : ACKRESULT_SUCCESS, (HANDLE)sc->lParam, wError);
- break;
-
- case SSA_IMPORT:
- if (wError)
- debugLogA("Re-starting import sequence failed, error %d", wError);
- else {
- setWord("SrvImportID", 0);
- delSetting("ImportTS");
- }
- break;
-
- default:
- debugLogA("Server ack cookie type (%d) not recognized.", sc->dwAction);
- }
-
- SAFE_FREE((void**)&sc); // free the memory
- return;
-}
-
-MCONTACT CIcqProto::HContactFromRecordName(const char* szRecordName, int *bAdded)
-{
- MCONTACT hContact = INVALID_CONTACT_ID;
-
- if (!IsStringUIN(szRecordName)) // probably AIM contact
- hContact = HContactFromUID(0, szRecordName, bAdded);
- else { // this should be ICQ number
- DWORD dwUin = atoi(szRecordName);
- hContact = HContactFromUIN(dwUin, bAdded);
- }
- return hContact;
-}
-
-int CIcqProto::getServerDataFromItemTLV(oscar_tlv_chain* pChain, unsigned char *buf) /// FIXME: need to keep original order
-{
- // get server-list item's TLV data
- oscar_tlv_chain* list = pChain;
- int datalen = 0;
- icq_packet pBuf;
-
- // Initialize our handy data buffer
- pBuf.wPlace = 0;
- pBuf.pData = buf;
-
- while (list) { // collect non-standard TLVs and save them to DB
- if (list->tlv.wType != SSI_TLV_AWAITING_AUTH &&
- list->tlv.wType != SSI_TLV_NAME &&
- list->tlv.wType != SSI_TLV_COMMENT &&
- list->tlv.wType != SSI_TLV_METAINFO_TOKEN &&
- list->tlv.wType != SSI_TLV_METAINFO_TIME) { // only TLVs which we do not handle on our own
- packTLV(&pBuf, list->tlv.wType, list->tlv.wLen, list->tlv.pData);
-
- datalen += list->tlv.wLen + 4;
- }
- list = list->next;
- }
- return datalen;
-}
-
-void CIcqProto::handleServerCListReply(BYTE *buf, size_t wLen, WORD wFlags, serverthread_info *info)
-{
- BYTE bySSIVersion;
- WORD wRecordCount;
- WORD wRecord;
- WORD wGroupId;
- WORD wItemId;
- WORD wTlvType;
- size_t wTlvLength;
- BOOL bIsLastPacket;
- uid_str szRecordName;
- oscar_tlv_chain* pChain = nullptr;
- oscar_tlv* pTLV = nullptr;
- char *szActiveSrvGroup = nullptr;
- WORD wActiveSrvGroupId = -1;
-
- // If flag bit 1 is set, this is not the last
- // packet. If it is 0, this is the last packet
- // and there will be a timestamp at the end.
- if (wFlags & 0x0001)
- bIsLastPacket = FALSE;
- else
- bIsLastPacket = TRUE;
-
- if (wLen < 3)
- return;
-
- // Version number of SSI protocol?
- unpackByte(&buf, &bySSIVersion);
- wLen -= 1;
-
- // Total count of following entries. This is the size of the server
- // side contact list and should be saved and sent with CLI_CHECKROSTER.
- // NOTE: When the entries are split up in several packets, each packet
- // has it's own count and they must be added to get the total size of
- // server list.
- unpackWord(&buf, &wRecordCount);
- wLen -= 2;
- debugLogA("SSI: number of entries is %u, version is %u", wRecordCount, bySSIVersion);
-
- // Loop over all items in the packet
- for (wRecord = 0; wRecord < wRecordCount; wRecord++) {
- debugLogA("SSI: parsing record %u", wRecord + 1);
-
- if (wLen < 10) { // minimum: name length (zero), group ID, item ID, empty TLV
- debugLogA("Warning: SSI parsing error (%d)", 0);
- break;
- }
-
- if (!unpackServerListItem(&buf, &wLen, szRecordName, &wGroupId, &wItemId, &wTlvType, &wTlvLength)) { // unpack basic structure
- debugLogA("Warning: SSI parsing error (%d)", 1);
- break;
- }
-
- debugLogA("Name: '%s', GroupID: %u, EntryID: %u, EntryType: %u, TLVlength: %u",
- szRecordName, wGroupId, wItemId, wTlvType, wTlvLength);
-
- if (wLen < wTlvLength) {
- debugLogA("Warning: SSI parsing error (%d)", 2);
- break;
- }
-
- // Initialize the tlv chain
- if (wTlvLength > 0) {
- pChain = readIntoTLVChain(&buf, wTlvLength, 0);
- wLen -= wTlvLength;
- }
- else pChain = nullptr;
-
- switch (wTlvType) {
- case SSI_ITEM_BUDDY:
- {
- /* this is a contact */
- int bAdded;
- MCONTACT hContact = HContactFromRecordName(szRecordName, &bAdded);
-
- if (hContact != INVALID_CONTACT_ID) {
- int bRegroup = 0;
- int bNicked = 0;
-
- if (bAdded) { // Not already on list: added
- debugLogA("SSI added new %s contact '%s'", "ICQ", szRecordName);
-
- AddJustAddedContact(hContact);
- }
- else { // we should add new contacts and this contact was just added, show it
- if (IsContactJustAdded(hContact)) {
- setContactHidden(hContact, 0);
- bAdded = 1; // we want details for new contacts
- }
- else debugLogA("SSI ignoring existing contact '%s'", szRecordName);
-
- // Contact on server is always on list
- db_set_b(hContact, "CList", "NotOnList", 0);
- }
-
- // Save group and item ID
- setWord(hContact, DBSETTING_SERVLIST_ID, wItemId);
- setWord(hContact, DBSETTING_SERVLIST_GROUP, wGroupId);
- ReserveServerID(wItemId, SSIT_ITEM, 0);
-
- if (!bAdded && getByte("LoadServerDetails", DEFAULT_SS_LOAD)) { // check if the contact has been moved on the server
- if (wActiveSrvGroupId != wGroupId || !szActiveSrvGroup) {
- SAFE_FREE(&szActiveSrvGroup);
- szActiveSrvGroup = getServListGroupCListPath(wGroupId);
- wActiveSrvGroupId = wGroupId;
- }
- char *szLocalGroup = getContactCListGroup(hContact);
-
- if (!mir_strlen(szLocalGroup)) { // no CListGroup
- SAFE_FREE(&szLocalGroup);
-
- szLocalGroup = null_strdup(DEFAULT_SS_GROUP);
- }
-
- if (mir_strcmp(szActiveSrvGroup, szLocalGroup) &&
- (mir_strlen(szActiveSrvGroup) >= mir_strlen(szLocalGroup) || (szActiveSrvGroup && _strnicmp(szActiveSrvGroup, szLocalGroup, mir_strlen(szLocalGroup))))) { // contact moved to new group or sub-group or not to master group
- bRegroup = 1;
- }
- if (bRegroup && !mir_strcmpi(DEFAULT_SS_GROUP, szActiveSrvGroup)) /// TODO: invent something more clever for "root" group
- { // is it the default "General" group ?
- bRegroup = 0; // if yes, do not move to it - cause it would hide the contact
- }
- SAFE_FREE(&szLocalGroup);
- }
-
- if (bRegroup || bAdded) { // if we should load server details or contact was just added, update its group
- if (wActiveSrvGroupId != wGroupId || !szActiveSrvGroup) {
- SAFE_FREE(&szActiveSrvGroup);
- szActiveSrvGroup = getServListGroupCListPath(wGroupId);
- wActiveSrvGroupId = wGroupId;
- }
-
- if (szActiveSrvGroup) { // try to get Miranda Group path from groupid, if succeeded save to db
- moveContactToCListGroup(hContact, szActiveSrvGroup);
- }
- }
-
- if (pChain) { // Look for nickname TLV and copy it to the db if necessary
- if (pTLV = pChain->getTLV(SSI_TLV_NAME, 1)) {
- if (pTLV->pData && (pTLV->wLen > 0)) {
- char *pszNick;
- WORD wNickLength;
-
- wNickLength = pTLV->wLen;
-
- pszNick = (char*)SAFE_MALLOC(wNickLength + 1);
- // Copy buffer to utf-8 buffer
- memcpy(pszNick, pTLV->pData, wNickLength);
- pszNick[wNickLength] = 0; // Terminate string
-
- debugLogA("Nickname is '%s'", pszNick);
-
- bNicked = 1;
-
- // Write nickname to database
- if (getByte("LoadServerDetails", DEFAULT_SS_LOAD) || bAdded) { // if just added contact, save details always - does no harm
- char *szOldNick;
-
- if (szOldNick = getSettingStringUtf(hContact, "CList", "MyHandle", nullptr)) {
- if ((mir_strcmp(szOldNick, pszNick)) && (mir_strlen(pszNick) > 0)) { // check if the truncated nick changed, i.e. do not overwrite locally stored longer nick
- if (mir_strlen(szOldNick) <= mir_strlen(pszNick) || strncmp(szOldNick, pszNick, null_strcut(szOldNick, MAX_SSI_TLV_NAME_SIZE))) {
- // Yes, we really do need to delete it first. Otherwise the CLUI nick
- // cache isn't updated (I'll look into it)
- db_unset(hContact, "CList", "MyHandle");
- db_set_utf(hContact, "CList", "MyHandle", pszNick);
- }
- }
- SAFE_FREE(&szOldNick);
- }
- else if (mir_strlen(pszNick) > 0) {
- db_unset(hContact, "CList", "MyHandle");
- db_set_utf(hContact, "CList", "MyHandle", pszNick);
- }
- }
- SAFE_FREE(&pszNick);
- }
- else debugLogA("Invalid nickname");
- }
- if (bAdded && !bNicked)
- icq_QueueUser(hContact); // queue user without nick for fast auto info update
-
- // Look for comment TLV and copy it to the db if necessary
- if (pTLV = pChain->getTLV(SSI_TLV_COMMENT, 1)) {
- if (pTLV->pData && (pTLV->wLen > 0)) {
- char *pszComment;
- WORD wCommentLength;
-
-
- wCommentLength = pTLV->wLen;
-
- pszComment = (char*)SAFE_MALLOC(wCommentLength + 1);
- // Copy buffer to utf-8 buffer
- memcpy(pszComment, pTLV->pData, wCommentLength);
- pszComment[wCommentLength] = 0; // Terminate string
-
- debugLogA("Comment is '%s'", pszComment);
-
- // Write comment to database
- if (getByte("LoadServerDetails", DEFAULT_SS_LOAD) || bAdded) { // if just added contact, save details always - does no harm
- char *szOldComment;
-
- if (szOldComment = getSettingStringUtf(hContact, "UserInfo", "MyNotes", nullptr)) {
- if ((mir_strcmp(szOldComment, pszComment)) && (mir_strlen(pszComment) > 0)) // check if the truncated comment changed, i.e. do not overwrite locally stored longer comment
- if (mir_strlen(szOldComment) <= mir_strlen(pszComment) || strncmp((char*)szOldComment, (char*)pszComment, null_strcut(szOldComment, MAX_SSI_TLV_COMMENT_SIZE)))
- db_set_utf(hContact, "UserInfo", "MyNotes", pszComment);
-
- SAFE_FREE((void**)&szOldComment);
- }
- else if (mir_strlen(pszComment) > 0)
- db_set_utf(hContact, "UserInfo", "MyNotes", pszComment);
- }
- SAFE_FREE((void**)&pszComment);
- }
- else debugLogA("Invalid comment");
- }
-
- // Look for need-authorization TLV
- if (pChain->getTLV(SSI_TLV_AWAITING_AUTH, 1)) {
- setByte(hContact, "Auth", 1);
- debugLogA("SSI contact need authorization");
- }
- else setByte(hContact, "Auth", 0);
-
- if (pTLV = pChain->getTLV(SSI_TLV_METAINFO_TOKEN, 1)) {
- setSettingBlob(hContact, DBSETTING_METAINFO_TOKEN, pTLV->pData, pTLV->wLen);
- if (pChain->getTLV(SSI_TLV_METAINFO_TIME, 1))
- setSettingDouble(hContact, DBSETTING_METAINFO_TIME, pChain->getDouble(SSI_TLV_METAINFO_TIME, 1));
- debugLogA("SSI contact has meta info token");
- }
- else {
- delSetting(hContact, DBSETTING_METAINFO_TOKEN);
- delSetting(hContact, DBSETTING_METAINFO_TIME);
- }
-
- { // store server-list item's TLV data
- BYTE* data = (BYTE*)SAFE_MALLOC(wTlvLength);
- int datalen = getServerDataFromItemTLV(pChain, data);
-
- if (datalen > 0)
- setSettingBlob(hContact, DBSETTING_SERVLIST_DATA, data, datalen);
- else
- delSetting(hContact, DBSETTING_SERVLIST_DATA);
-
- SAFE_FREE((void**)&data);
- }
- }
- }
- else // failed to add or other error
- debugLogA("SSI failed to handle %s Item '%s'", "Buddy", szRecordName);
- }
- break;
-
- case SSI_ITEM_GROUP:
- if ((wGroupId == 0) && (wItemId == 0)) {
- /* list of groups. wTlvType=1, data is TLV(C8) containing list of WORDs which */
- /* is the group ids
- /* we don't need to use this. Our processing is on-the-fly */
- /* this record is always sent first in the first packet only, */
- }
- else if (wGroupId != 0) {
- /* wGroupId != 0: a group record */
- if (wItemId == 0) { /* no item ID: this is a group */
- /* pszRecordName is the name of the group */
- ReserveServerID(wGroupId, SSIT_GROUP, 0);
-
- setServListGroupName(wGroupId, szRecordName);
-
- debugLogA("Group %s added to known groups.", szRecordName);
-
- /* demangle full grouppath, set it to known */
- SAFE_FREE(&szActiveSrvGroup);
- szActiveSrvGroup = getServListGroupCListPath(wGroupId);
- wActiveSrvGroupId = wGroupId;
-
- /* TLV contains a TLV(C8) with a list of WORDs of contained contact IDs */
- /* our processing is good enough that we don't need this duplication */
- }
- else debugLogA("Unhandled type 0x01, wItemID != 0");
- }
- else debugLogA("Unhandled type 0x01");
- break;
-
- case SSI_ITEM_PERMIT:
- {
- /* item on visible list */
- /* wItemId not related to contact ID */
- /* pszRecordName is the UIN */
- int bAdded;
- MCONTACT hContact = HContactFromRecordName(szRecordName, &bAdded);
-
- if (hContact != INVALID_CONTACT_ID) {
- if (bAdded) {
- debugLogA("SSI added new %s contact '%s'", "Permit", szRecordName);
- // It wasn't previously in the list, we hide it so it only appears in the visible list
- setContactHidden(hContact, 1);
- // Add it to the list, so it can be added properly if proper contact
- AddJustAddedContact(hContact);
- }
- else debugLogA("SSI %s contact already exists '%s'", "Permit", szRecordName);
-
- // Save permit ID
- setWord(hContact, DBSETTING_SERVLIST_PERMIT, wItemId);
- ReserveServerID(wItemId, SSIT_ITEM, 0);
- // Set apparent mode
- setWord(hContact, "ApparentMode", ID_STATUS_ONLINE);
- debugLogA("Visible-contact (%s)", szRecordName);
- }
- else { // failed to add or other error
- debugLogA("SSI failed to handle %s Item '%s'", "Permit", szRecordName);
- ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED);
- }
- }
- break;
-
- case SSI_ITEM_DENY:
- {
- /* Item on invisible list */
- /* wItemId not related to contact ID */
- /* pszRecordName is the UIN */
- int bAdded;
- MCONTACT hContact = HContactFromRecordName(szRecordName, &bAdded);
-
- if (hContact != INVALID_CONTACT_ID) {
- if (bAdded) {
- /* not already on list: added */
- debugLogA("SSI added new %s contact '%s'", "Deny", szRecordName);
- // It wasn't previously in the list, we hide it so it only appears in the visible list
- setContactHidden(hContact, 1);
- // Add it to the list, so it can be added properly if proper contact
- AddJustAddedContact(hContact);
- }
- else debugLogA("SSI %s contact already exists '%s'", "Deny", szRecordName);
-
- // Save Deny ID
- setWord(hContact, DBSETTING_SERVLIST_DENY, wItemId);
- ReserveServerID(wItemId, SSIT_ITEM, 0);
-
- // Set apparent mode
- setWord(hContact, "ApparentMode", ID_STATUS_OFFLINE);
- debugLogA("Invisible-contact (%s)", szRecordName);
- }
- else { // failed to add or other error
- debugLogA("SSI failed to handle %s Item '%s'", "Deny", szRecordName);
- ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED);
- }
- }
- break;
-
- case SSI_ITEM_VISIBILITY: /* My visibility settings */
- // Look for visibility TLV
- if (BYTE bVisibility = pChain->getByte(SSI_TLV_VISIBILITY, 1)) { // found it, store the id, we do not need current visibility - we do not rely on it
- setWord(DBSETTING_SERVLIST_PRIVACY, wItemId);
- ReserveServerID(wItemId, SSIT_ITEM, 0);
-
- debugLogA("Visibility is %u", bVisibility);
- }
- else ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED);
- break;
-
- case SSI_ITEM_IGNORE:
- {
- /* item on ignore list */
- /* wItemId not related to contact ID */
- /* pszRecordName is the UIN */
- int bAdded;
- MCONTACT hContact = HContactFromRecordName(szRecordName, &bAdded);
-
- if (hContact != INVALID_CONTACT_ID) {
- if (bAdded) {
- /* not already on list: add */
- debugLogA("SSI added new %s contact '%s'", "Ignore", szRecordName);
- // It wasn't previously in the list, we hide it
- setContactHidden(hContact, 1);
- // Add it to the list, so it can be added properly if proper contact
- AddJustAddedContact(hContact);
- }
- else debugLogA("SSI %s contact already exists '%s'", "Ignore", szRecordName);
-
- // Save Ignore ID
- setWord(hContact, DBSETTING_SERVLIST_IGNORE, wItemId);
- ReserveServerID(wItemId, SSIT_ITEM, 0);
-
- // Set apparent mode & ignore
- setWord(hContact, "ApparentMode", ID_STATUS_OFFLINE);
- // set ignore all events
- CallService(MS_IGNORE_IGNORE, hContact, IGNOREEVENT_ALL);
- debugLogA("Ignore-contact (%s)", szRecordName);
- }
- else { // failed to add or other error
- debugLogA("SSI failed to handle %s Item '%s'", "Ignore", szRecordName);
- ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED);
- }
- }
- break;
-
- case SSI_ITEM_UNKNOWN2:
- debugLogA("SSI unknown type 0x11");
-
- ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED);
- break;
-
- case SSI_ITEM_IMPORTTIME:
- if (wGroupId == 0) {
- /* time our list was first imported */
- /* pszRecordName is "Import Time" */
- /* data is TLV(13) {TLV(D4) {time_t importTime}} */
- setDword("ImportTS", pChain->getDWord(SSI_TLV_TIMESTAMP, 1));
- setWord("SrvImportID", wItemId);
- ReserveServerID(wItemId, SSIT_ITEM, 0);
- debugLogA("SSI %s item recognized", "first import");
- }
- break;
-
- case SSI_ITEM_BUDDYICON:
- if (wGroupId == 0) {
- /* our avatar MD5-hash */
- /* pszRecordName is "1" */
- /* data is TLV(D5) hash */
- /* we ignore this, just save the id */
- /* cause we get the hash again after login */
- if (!mir_strcmp(szRecordName, "12")) { // need to handle Photo Item separately
- setWord(DBSETTING_SERVLIST_PHOTO, wItemId);
- debugLogA("SSI %s item recognized", "Photo");
- }
- else {
- setWord(DBSETTING_SERVLIST_AVATAR, wItemId);
- debugLogA("SSI %s item recognized", "Avatar");
- }
- ReserveServerID(wItemId, SSIT_ITEM, 0);
- }
- break;
-
- case SSI_ITEM_METAINFO:
- if (wGroupId == 0) {
- /* our meta info token & last update time */
- /* pszRecordName is "ICQ-MDIR" */
- /* data is TLV(15C) and TLV(15D) */
- oscar_tlv* pToken = pChain->getTLV(SSI_TLV_METAINFO_TOKEN, 1);
- oscar_tlv* pTime = pChain->getTLV(SSI_TLV_METAINFO_TIME, 1);
- if (pToken)
- setSettingBlob(NULL, DBSETTING_METAINFO_TOKEN, pToken->pData, pToken->wLen);
- if (pTime)
- setSettingDouble(NULL, DBSETTING_METAINFO_TIME, pChain->getDouble(SSI_TLV_METAINFO_TIME, 1));
-
- setWord(DBSETTING_SERVLIST_METAINFO, wItemId);
- ReserveServerID(wItemId, SSIT_ITEM, 0);
-
- debugLogA("SSI %s item recognized", "Meta info");
- }
- break;
-
- case SSI_ITEM_CLIENTDATA:
- if (wGroupId == 0) {
- /* ICQ2k ShortcutBar Items */
- /* data is TLV(CD) text */
- if (wItemId)
- ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED);
- }
-
- case SSI_ITEM_SAVED:
- case SSI_ITEM_PREAUTH:
- break;
-
- default:
- debugLogA("SSI unhandled item %2x", wTlvType);
-
- if (wItemId)
- ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED);
- break;
- }
-
- disposeChain(&pChain);
- } // end for
-
- // Release Memory
- SAFE_FREE(&szActiveSrvGroup);
-
- debugLogA("Bytes left: %u", wLen);
-
- setWord("SrvRecordCount", (WORD)(wRecord + getWord("SrvRecordCount", 0)));
-
- if (bIsLastPacket) {
- // No contacts left to sync
- bIsSyncingCL = FALSE;
-
- StoreServerIDs();
-
- icq_RescanInfoUpdate();
-
- if (wLen >= 4) {
- DWORD dwLastUpdateTime;
-
- /* finally we get a time_t of the last update time */
- unpackDWord(&buf, &dwLastUpdateTime);
- setDword("SrvLastUpdate", dwLastUpdateTime);
- debugLogA("Last update of server list was (%u) %s", dwLastUpdateTime, time2text(dwLastUpdateTime));
-
- sendRosterAck();
- handleServUINSettings(wListenPort, info);
-
- servlistProcessLogin();
- }
- else debugLogA("Last packet missed update time...");
-
- if (getWord("SrvRecordCount", 0) == 0) { // we got empty serv-list, create master group
- cookie_servlist_action* ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (ack) {
- DWORD dwCookie;
-
- ack->dwAction = SSA_GROUP_UPDATE;
- ack->szGroupName = null_strdup("");
- dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, 0, ack);
- icq_sendServerGroup(dwCookie, ICQ_LISTS_ADDTOLIST, 0, ack->szGroupName, nullptr, 0, 0);
- }
- }
- // serv-list sync finished, clear just added contacts
- FlushJustAddedContacts();
- }
- else debugLogA("Waiting for more packets");
-}
-
-void CIcqProto::handleServerCListItemAdd(WORD wItemId, WORD wItemType, oscar_tlv_chain *pItemData)
-{
- if (wItemType == SSI_ITEM_IMPORTTIME) {
- if (pItemData) {
- setDword("ImportTS", pItemData->getDWord(SSI_TLV_TIMESTAMP, 1));
- setWord("SrvImportID", wItemId);
- ReserveServerID(wItemId, SSIT_ITEM, 0);
-
- debugLogA("Server added Import timestamp to list");
- return;
- }
- }
- // Reserve server-list ID
- ReserveServerID(wItemId, wItemType == SSI_ITEM_GROUP ? SSIT_GROUP : SSIT_ITEM, SSIF_UNHANDLED);
-}
-
-void CIcqProto::handleServerCListItemUpdate(const char *szRecordName, WORD wItemType, oscar_tlv_chain *pItemData)
-{
- MCONTACT hContact = (wItemType == SSI_ITEM_BUDDY || wItemType == SSI_ITEM_DENY || wItemType == SSI_ITEM_PERMIT || wItemType == SSI_ITEM_IGNORE) ? HContactFromRecordName(szRecordName, nullptr) : NULL;
-
- if (hContact != INVALID_CONTACT_ID && wItemType == SSI_ITEM_BUDDY) { // a contact was updated on server
- if (pItemData) {
- oscar_tlv *pAuth = pItemData->getTLV(SSI_TLV_AWAITING_AUTH, 1);
- BYTE bAuth = getByte(hContact, "Auth", 0);
-
- if (bAuth && !pAuth) { // server authorized our contact
- char str[MAX_PATH];
- char msg[MAX_PATH];
- char *nick = NickFromHandleUtf(hContact);
-
- setByte(hContact, "Auth", 0);
- mir_snprintf(str, ICQTranslateUtfStatic(LPGEN("Contact \"%s\" was authorized in the server list."), msg, _countof(msg)), nick);
- icq_LogMessage(LOG_WARNING, str);
- SAFE_FREE(&nick);
- }
- else if (!bAuth && pAuth) { // server took away authorization of our contact
- char str[MAX_PATH];
- char msg[MAX_PATH];
- char *nick = NickFromHandleUtf(hContact);
-
- setByte(hContact, "Auth", 1);
- mir_snprintf(str, ICQTranslateUtfStatic(LPGEN("Contact \"%s\" lost its authorization in the server list."), msg, _countof(msg)), nick);
- icq_LogMessage(LOG_WARNING, str);
- SAFE_FREE(&nick);
- }
- {
- // update metainfo data
- DBVARIANT dbv = { 0 };
- oscar_tlv *pToken = pItemData->getTLV(SSI_TLV_METAINFO_TOKEN, 1);
- oscar_tlv *pTime = pItemData->getTLV(SSI_TLV_METAINFO_TIME, 1);
-
- if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &dbv)) {
- if (!pToken || dbv.cpbVal != pToken->wLen || memcmp(dbv.pbVal, pToken->pData, dbv.cpbVal)) {
- if (!pToken)
- debugLogA("Contact %s, meta info token removed", szRecordName);
- else
- debugLogA("Contact %s, meta info token changed", szRecordName);
-
- // user info was changed, refresh
- if (IsMetaInfoChanged(hContact))
- icq_QueueUser(hContact);
- }
-
- db_free(&dbv);
- }
- else if (pToken) {
- debugLogA("Contact %s, meta info token added", szRecordName);
-
- // user info was changed, refresh
- if (IsMetaInfoChanged(hContact))
- icq_QueueUser(hContact);
- }
-
- if (pToken)
- setSettingBlob(hContact, DBSETTING_METAINFO_TOKEN, pToken->pData, pToken->wLen);
- if (pTime)
- setSettingDouble(hContact, DBSETTING_METAINFO_TIME, pItemData->getDouble(SSI_TLV_METAINFO_TIME, 1));
- }
- {
- // update server's data - otherwise consequent operations can fail with 0x0E
- BYTE *data = (BYTE*)_alloca(pItemData->getChainLength());
- int datalen = getServerDataFromItemTLV(pItemData, data);
-
- if (datalen > 0)
- setSettingBlob(hContact, DBSETTING_SERVLIST_DATA, data, datalen);
- else
- delSetting(hContact, DBSETTING_SERVLIST_DATA);
- }
- }
- }
- else if (wItemType == SSI_ITEM_METAINFO) { // owner MetaInfo data updated
- if (pItemData) {
- DBVARIANT dbv = { 0 };
- oscar_tlv *pToken = pItemData->getTLV(SSI_TLV_METAINFO_TOKEN, 1);
- oscar_tlv *pTime = pItemData->getTLV(SSI_TLV_METAINFO_TIME, 1);
-
- if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &dbv)) {
- if (!pToken || dbv.cpbVal != pToken->wLen || memcmp(dbv.pbVal, pToken->pData, dbv.cpbVal)) {
- if (!pToken)
- debugLogA("Owner meta info token removed");
- else
- debugLogA("Owner meta info token changed");
- }
-
- db_free(&dbv);
- }
-
- if (pToken)
- setSettingBlob(hContact, DBSETTING_METAINFO_TOKEN, pToken->pData, pToken->wLen);
- if (pTime)
- setSettingDouble(hContact, DBSETTING_METAINFO_TIME, pItemData->getDouble(SSI_TLV_METAINFO_TIME, 1));
- }
- }
- else if (wItemType == SSI_ITEM_GROUP) // group updated
- debugLogA("Server updated our group \"%s\" on list", szRecordName);
-}
-
-void CIcqProto::handleServerCListItemDelete(const char *szRecordName, WORD wItemId, WORD wItemType)
-{
- MCONTACT hContact = (wItemType == SSI_ITEM_BUDDY || wItemType == SSI_ITEM_DENY || wItemType == SSI_ITEM_PERMIT || wItemType == SSI_ITEM_IGNORE) ? HContactFromRecordName(szRecordName, nullptr) : NULL;
-
- if (hContact != INVALID_CONTACT_ID && wItemType == SSI_ITEM_BUDDY) { // a contact was removed from our list
- if (getWord(hContact, DBSETTING_SERVLIST_ID, 0) == wItemId) {
- delSetting(hContact, DBSETTING_SERVLIST_ID);
- delSetting(hContact, DBSETTING_SERVLIST_GROUP);
- delSetting(hContact, "Auth");
-
- char str[MAX_PATH];
- char msg[MAX_PATH];
- char *nick = NickFromHandleUtf(hContact);
-
- mir_snprintf(str, ICQTranslateUtfStatic(LPGEN("User \"%s\" was removed from server list."), msg, _countof(msg)), nick);
- icq_LogMessage(LOG_WARNING, str);
- SAFE_FREE(&nick);
- }
- }
- // Release server-list ID
- FreeServerID(wItemId, wItemType == SSI_ITEM_GROUP ? SSIT_GROUP : SSIT_ITEM);
-}
-
-void CIcqProto::handleRecvAuthRequest(BYTE *buf, size_t wLen)
-{
- DWORD dwUin;
- uid_str szUid;
- if (!unpackUID(&buf, &wLen, &dwUin, &szUid))
- return;
-
- if (dwUin && IsOnSpammerList(dwUin)) {
- debugLogA("Ignored Message from known Spammer");
- return;
- }
-
- WORD wReasonLen;
- unpackWord(&buf, &wReasonLen);
- wLen -= 2;
- if (wReasonLen > wLen)
- return;
-
- int bAdded;
- MCONTACT hContact = HContactFromUID(dwUin, szUid, &bAdded);
-
- // Prepare reason
- char *szReason = (char*)SAFE_MALLOC(wReasonLen + 1);
- if (szReason) {
- memcpy(szReason, buf, wReasonLen);
- szReason[wReasonLen] = '\0';
- }
-
- // Read nick name from DB
- char *szNick;
- if (dwUin)
- szNick = getSettingStringUtf(hContact, "Nick", nullptr);
- else
- szNick = null_strdup(szUid);
-
- DB_AUTH_BLOB blob(hContact, szNick, nullptr, nullptr, nullptr, szReason);
- blob.set_uin(dwUin);
-
- setByte(hContact, "Grant", 1);
-
- // TODO: Change for new auth system, include all known informations
- PROTORECVEVENT pre = { 0 };
- pre.timestamp = time(0);
- pre.lParam = blob.size();
- pre.szMessage = blob;
- ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre);
-
- SAFE_FREE(&szNick);
- SAFE_FREE(&szReason);
-}
-
-void CIcqProto::handleRecvAdded(BYTE *buf, size_t wLen)
-{
- PBYTE pBlob, pCurBlob;
- DBVARIANT dbv = { 0 };
-
- DWORD dwUin;
- uid_str szUid;
- if (!unpackUID(&buf, &wLen, &dwUin, &szUid))
- return;
-
- if (dwUin && IsOnSpammerList(dwUin)) {
- debugLogA("Ignored Message from known Spammer");
- return;
- }
-
- int bAdded;
- MCONTACT hContact = HContactFromUID(dwUin, szUid, &bAdded);
-
- size_t nNickLen, cbBlob = sizeof(DWORD) * 2 + 4;
-
- char *szNick = nullptr;
- if (dwUin) {
- if (getString(hContact, "Nick", &dbv))
- nNickLen = 0;
- else {
- szNick = dbv.pszVal;
- nNickLen = mir_strlen(szNick);
- }
- }
- else nNickLen = mir_strlen(szUid);
-
- cbBlob += nNickLen;
-
- pCurBlob = pBlob = (PBYTE)_alloca(cbBlob);
- /*blob is: uin(DWORD), hContact(HANDLE), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ) */
- *(DWORD*)pCurBlob = dwUin; pCurBlob += sizeof(DWORD);
- *(DWORD*)pCurBlob = hContact; pCurBlob += sizeof(DWORD);
- if (nNickLen && dwUin) { // if we have nick we add it, otherwise keep trailing zero
- memcpy(pCurBlob, szNick, nNickLen);
- pCurBlob += nNickLen;
- }
- else {
- memcpy(pCurBlob, szUid, nNickLen);
- pCurBlob += nNickLen;
- }
- *(char*)pCurBlob = 0; pCurBlob++;
- *(char*)pCurBlob = 0; pCurBlob++;
- *(char*)pCurBlob = 0; pCurBlob++;
- *(char*)pCurBlob = 0;
- // TODO: Change for new auth system
-
- AddEvent(NULL, EVENTTYPE_ADDED, time(0), 0, cbBlob, pBlob);
-}
-
-void CIcqProto::handleRecvAuthResponse(BYTE *buf, size_t wLen)
-{
- DWORD dwUin;
- uid_str szUid;
- char* szNick = nullptr;
- WORD nReasonLen;
- char* szReason;
- int bAdded;
-
- BYTE bResponse = 0xFF;
-
- if (!unpackUID(&buf, &wLen, &dwUin, &szUid)) return;
-
- if (dwUin && IsOnSpammerList(dwUin)) {
- debugLogA("Ignored Message from known Spammer");
- return;
- }
-
- MCONTACT hContact = HContactFromUID(dwUin, szUid, &bAdded);
- if (hContact != INVALID_CONTACT_ID)
- szNick = NickFromHandle(hContact);
-
- if (wLen > 0) {
- unpackByte(&buf, &bResponse);
- wLen -= 1;
- }
- if (wLen >= 2) {
- unpackWord(&buf, &nReasonLen);
- wLen -= 2;
- if (wLen >= nReasonLen) {
- szReason = (char*)_alloca(nReasonLen + 1);
- unpackString(&buf, szReason, nReasonLen);
- szReason[nReasonLen] = '\0';
- }
- }
-
- switch (bResponse) {
- case 0:
- debugLogA("Authorization request %s by %s", "denied", strUID(dwUin, szUid));
- // TODO: Add to system history as soon as new auth system is ready
- break;
-
- case 1:
- setByte(hContact, "Auth", 0);
- debugLogA("Authorization request %s by %s", "granted", strUID(dwUin, szUid));
- // TODO: Add to system history as soon as new auth system is ready
- break;
-
- default:
- debugLogA("Unknown Authorization request response (%u) from %s", bResponse, strUID(dwUin, szUid));
- break;
-
- }
- SAFE_FREE(&szNick);
-}
-
-// Updates the visibility code used while in SSI mode. If a server ID is
-// not stored in the local DB, a new ID will be added to the server list.
-//
-// Possible values are:
-// 01 - Allow all users to see you
-// 02 - Block all users from seeing you
-// 03 - Allow only users in the permit list to see you
-// 04 - Block only users in the invisible list from seeing you
-// 05 - Allow only users in the buddy list to see you
-//
-void CIcqProto::updateServVisibilityCode(BYTE bCode)
-{
- icq_packet packet;
- WORD wVisibilityID;
- WORD wCommand;
-
- if ((bCode > 0) && (bCode < 6)) {
- cookie_servlist_action* ack;
- DWORD dwCookie;
- BYTE bVisibility = getByte("SrvVisibility", 0);
-
- if (bVisibility == bCode) // if no change was made, not necescary to update that
- return;
- setByte("SrvVisibility", bCode);
-
- // Do we have a known server visibility ID? We should, unless we just subscribed to the serv-list for the first time
- if ((wVisibilityID = getWord(DBSETTING_SERVLIST_PRIVACY, 0)) == 0) {
- // No, create a new random ID
- wVisibilityID = GenerateServerID(SSIT_ITEM, 0);
- setWord(DBSETTING_SERVLIST_PRIVACY, wVisibilityID);
- wCommand = ICQ_LISTS_ADDTOLIST;
-
- debugLogA("Made new srvVisibilityID, id is %u, code is %u", wVisibilityID, bCode);
- }
- else {
- debugLogA("Reused srvVisibilityID, id is %u, code is %u", wVisibilityID, bCode);
- wCommand = ICQ_LISTS_UPDATEGROUP;
- }
-
- ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (!ack) {
- debugLogA("Cookie alloc failure.");
- return; // out of memory, go away
- }
-
- ack->dwAction = SSA_VISIBILITY; // update visibility
- dwCookie = AllocateCookie(CKT_SERVERLIST, wCommand, 0, ack); // take cookie
-
- // Build and send packet
- serverPacketInit(&packet, 25);
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, wCommand, 0, dwCookie);
- packWord(&packet, 0); // Name (null)
- packWord(&packet, 0); // GroupID (0 if not relevant)
- packWord(&packet, wVisibilityID); // EntryID
- packWord(&packet, SSI_ITEM_VISIBILITY); // EntryType
- packWord(&packet, 5); // Length in bytes of following TLV
- packTLV(&packet, SSI_TLV_VISIBILITY, 1, &bCode); // TLV (Visibility)
- sendServPacket(&packet);
- // There is no need to send ICQ_LISTS_CLI_MODIFYSTART or
- // ICQ_LISTS_CLI_MODIFYEND when modifying the visibility code
- }
-}
-
-// Updates the avatar hash used while in SSI mode. If a server ID is
-// not stored in the local DB, a new ID will be added to the server list.
-void CIcqProto::updateServAvatarHash(BYTE *pHash, int size)
-{
- void** pDoubleObject = nullptr;
- void* doubleObject = nullptr;
- DWORD dwOperationFlags = 0;
- WORD wAvatarID;
- WORD wCommand;
- char szItemName[2] = { 0, 0 };
- int bResetHash = 0;
- DBVARIANT dbvHash;
-
- if (!pHash)
- return;
-
- if (!getSetting(NULL, "AvatarHash", &dbvHash)) {
- szItemName[0] = 0x30 + dbvHash.pbVal[1];
-
- if (memcmp(pHash, dbvHash.pbVal, 2) != 0) // add code to remove old hash from server
- bResetHash = 1;
-
- db_free(&dbvHash);
- }
-
- if (bResetHash) { // start update session
- // pair the packets (need to be send in the correct order
- dwOperationFlags |= SSOF_BEGIN_OPERATION | SSOF_END_OPERATION;
- pDoubleObject = &doubleObject;
- }
-
- if (bResetHash) {
- // Do we have a known server avatar ID?
- if (wAvatarID = getWord(DBSETTING_SERVLIST_AVATAR, 0)) {
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (!ack) {
- debugLogA("Cookie alloc failure.");
- return; // out of memory, go away
- }
- ack->dwAction = SSA_REMOVEAVATAR; // update avatar hash
- ack->wContactId = wAvatarID;
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, 0, ack); // take cookie
- icq_sendServerItem(dwCookie, ICQ_LISTS_REMOVEFROMLIST, 0, wAvatarID, szItemName, nullptr, 0, SSI_ITEM_BUDDYICON, SSOP_ITEM_ACTION | dwOperationFlags, 400, pDoubleObject);
- }
- }
-
- WORD hashsize = size - 2;
-
- // Do we have a known server avatar ID? We should, unless we just subscribed to the serv-list for the first time
- if (bResetHash || (wAvatarID = getWord(DBSETTING_SERVLIST_AVATAR, 0)) == 0) {
- // No, create a new random ID
- wAvatarID = GenerateServerID(SSIT_ITEM, 0);
- wCommand = ICQ_LISTS_ADDTOLIST;
- debugLogA("Made new srvAvatarID, id is %u", wAvatarID);
- }
- else {
- debugLogA("Reused srvAvatarID, id is %u", wAvatarID);
- wCommand = ICQ_LISTS_UPDATEGROUP;
- }
-
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (!ack) {
- debugLogA("Cookie alloc failure.");
- return; // out of memory, go away
- }
- ack->dwAction = SSA_SETAVATAR; // update avatar hash
- ack->wContactId = wAvatarID;
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, wCommand, 0, ack); // take cookie
-
- szItemName[0] = 0x30 + pHash[1];
-
- // Build the packet
- WORD wTLVlen = 8 + hashsize;
-
- // Initialize our handy data buffer
- icq_packet pBuffer;
- pBuffer.wPlace = 0;
- pBuffer.pData = (BYTE *)_alloca(wTLVlen);
- pBuffer.wLen = wTLVlen;
-
- packTLV(&pBuffer, SSI_TLV_NAME, 0, nullptr); // TLV (Name)
- packTLV(&pBuffer, SSI_TLV_AVATARHASH, hashsize, pHash + 2); // TLV (Hash)
-
- icq_sendServerItem(dwCookie, wCommand, 0, wAvatarID, szItemName, pBuffer.pData, wTLVlen, SSI_ITEM_BUDDYICON, SSOP_ITEM_ACTION | dwOperationFlags, 400, pDoubleObject);
- // There is no need to send ICQ_LISTS_CLI_MODIFYSTART or
- // ICQ_LISTS_CLI_MODIFYEND when modifying the avatar hash
-}
-
-// Should be called before the server list is modified. When all
-// modifications are done, call icq_sendServerEndOperation().
-// Called automatically thru server-list update board!
-void CIcqProto::icq_sendServerBeginOperation(int bImport)
-{
- WORD wImportID = getWord("SrvImportID", 0);
-
- if (bImport && wImportID) { // we should be importing, check if already have import item
- if (getDword("ImportTS", 0) + 604800 < getDword("LogonTS", 0)) { // is the timestamp week older, clear it and begin new import
- DWORD dwCookie;
- cookie_servlist_action* ack;
-
- if (ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action))) { // we have cookie good, go on
- ack->dwAction = SSA_IMPORT;
- dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, 0, ack);
-
- icq_sendSimpleItem(dwCookie, ICQ_LISTS_REMOVEFROMLIST, 0, "ImportTime", 0, wImportID, SSI_ITEM_IMPORTTIME, SSOP_ITEM_ACTION | SSOF_SEND_DIRECTLY, 100);
- }
- }
- }
-
- icq_packet packet;
- serverPacketInit(&packet, bImport ? 14 : 10);
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_MODIFYSTART);
- if (bImport)
- packDWord(&packet, 1 << 0x10);
- sendServPacket(&packet);
-}
-
-// Should be called after the server list has been modified to inform
-// the server that we are done.
-// Called automatically thru server-list update board!
-void CIcqProto::icq_sendServerEndOperation()
-{
- icq_packet packet;
- serverPacketInit(&packet, 10);
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_MODIFYEND);
- sendServPacket(&packet);
-}
-
-// Sent when the last roster packet has been received
-void CIcqProto::sendRosterAck(void)
-{
- icq_packet packet;
- serverPacketInit(&packet, 10);
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_GOTLIST);
- sendServPacket(&packet);
-
- debugLogA("Sent SNAC(x13,x07) - CLI_ROSTERACK");
-}
diff --git a/protocols/IcqOscarJ/src/fam_15icqserver.cpp b/protocols/IcqOscarJ/src/fam_15icqserver.cpp
deleted file mode 100644
index db4509ec21..0000000000
--- a/protocols/IcqOscarJ/src/fam_15icqserver.cpp
+++ /dev/null
@@ -1,1068 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleIcqExtensionsFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader)
-{
- switch (pSnacHeader->wSubtype) {
- case ICQ_META_ERROR:
- handleExtensionError(pBuffer, wBufferLength);
- break;
-
- case ICQ_META_SRV_REPLY:
- handleExtensionServerInfo(pBuffer, wBufferLength, pSnacHeader->wFlags);
- break;
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_EXTENSIONS_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-
-void CIcqProto::handleExtensionError(BYTE *buf, size_t wPackLen)
-{
- WORD wErrorCode;
-
- if (wPackLen < 2)
- wErrorCode = 0;
-
- if (wPackLen >= 2 && wPackLen <= 6)
- unpackWord(&buf, &wErrorCode);
- else {
- // TODO: cookies need to be handled and freed here on error
- unpackWord(&buf, &wErrorCode);
- wPackLen -= 2;
-
- oscar_tlv_chain *chain = readIntoTLVChain(&buf, wPackLen, 0);
- if (chain) {
- oscar_tlv* pTLV;
-
- pTLV = chain->getTLV(0x21, 1); // get meta error data
- if (pTLV && pTLV->wLen >= 8) {
- BYTE *pBuffer = pTLV->pData;
- WORD wData;
- pBuffer += 6;
- unpackLEWord(&pBuffer, &wData); // get request type
- switch (wData) {
- case CLI_META_INFO_REQ:
- if (pTLV->wLen >= 12) {
- WORD wSubType;
- WORD wCookie;
-
- unpackWord(&pBuffer, &wCookie);
- unpackLEWord(&pBuffer, &wSubType);
- // more sofisticated detection, send ack
- if (wSubType == META_REQUEST_FULL_INFO) {
- MCONTACT hContact;
- cookie_fam15_data *pCookieData = nullptr;
-
- int foundCookie = FindCookie(wCookie, &hContact, (void**)&pCookieData);
- if (foundCookie && pCookieData) {
- ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0);
-
- ReleaseCookie(wCookie); // we do not leak cookie and memory
- }
-
- debugLogA("Full info request error 0x%02x received", wErrorCode);
- }
- else if (wSubType == META_SET_PASSWORD_REQ) {
- // failed to change user password, report to UI
- ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_FAILED, (HANDLE)wCookie, 0);
-
- debugLogA("Meta change password request failed, error 0x%02x", wErrorCode);
- }
- else debugLogA("Meta request error 0x%02x received", wErrorCode);
- }
- else debugLogA("Meta request error 0x%02x received", wErrorCode);
- break;
-
- default:
- debugLogA("Unknown request 0x%02x error 0x%02x received", wData, wErrorCode);
- }
- disposeChain(&chain);
- return;
- }
- disposeChain(&chain);
- }
- }
- LogFamilyError(ICQ_EXTENSIONS_FAMILY, wErrorCode);
-}
-
-void CIcqProto::handleExtensionServerInfo(BYTE *buf, size_t wPackLen, WORD wFlags)
-{
- // The entire packet is encapsulated in a TLV type 1
- oscar_tlv_chain *chain = readIntoTLVChain(&buf, wPackLen, 0);
- if (chain == nullptr) {
- debugLogA("Error: Broken snac 15/3 %d", 1);
- return;
- }
-
- oscar_tlv *dataTlv = chain->getTLV(0x0001, 1);
- if (dataTlv == nullptr) {
- disposeChain(&chain);
- debugLogA("Error: Broken snac 15/3 %d", 2);
- return;
- }
-
- BYTE *databuf = dataTlv->pData;
- wPackLen -= 4;
-
- _ASSERTE(dataTlv->wLen == wPackLen);
- _ASSERTE(wPackLen >= 10);
-
- if ((dataTlv->wLen == wPackLen) && (wPackLen >= 10)) {
- DWORD dwMyUin;
- WORD wBytesRemaining, wCookie, wRequestType;
- unpackLEWord(&databuf, &wBytesRemaining);
- unpackLEDWord(&databuf, &dwMyUin);
- unpackLEWord(&databuf, &wRequestType);
- unpackWord(&databuf, &wCookie);
-
- _ASSERTE(wBytesRemaining == (wPackLen - 2));
- if (wBytesRemaining == (wPackLen - 2)) {
- wPackLen -= 10;
- switch (wRequestType) {
- case SRV_META_INFO_REPLY: // SRV_META request replies
- handleExtensionMetaResponse(databuf, wPackLen, wCookie, wFlags);
- break;
-
- default:
- debugLogA("Warning: Ignoring Meta response - Unknown type %d", wRequestType);
- break;
- }
- }
- }
- else debugLogA("Error: Broken snac 15/3 %d", 3);
-
- if (chain)
- disposeChain(&chain);
-}
-
-
-void CIcqProto::handleExtensionMetaResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie, WORD wFlags)
-{
- WORD wReplySubtype;
- BYTE bResultCode;
-
- _ASSERTE(wPacketLen >= 3);
- if (wPacketLen >= 3) {
- // Reply subtype
- unpackLEWord(&databuf, &wReplySubtype);
- wPacketLen -= 2;
-
- // Success byte
- unpackByte(&databuf, &bResultCode);
- wPacketLen -= 1;
-
- switch (wReplySubtype) {
- case META_SET_PASSWORD_ACK:
- parseUserInfoUpdateAck(wCookie, wReplySubtype, bResultCode);
- break;
-
- case SRV_RANDOM_FOUND:
- case SRV_USER_FOUND:
- case SRV_LAST_USER_FOUND:
- parseSearchReplies(databuf, wPacketLen, wCookie, wReplySubtype, bResultCode);
- break;
-
- case META_PROCESSING_ERROR: // Meta processing error server reply
- // Todo: We only use this as an SMS ack, that will have to change
- {
- // Terminate buffer
- char *pszInfo = (char *)_alloca(wPacketLen + 1);
- if (wPacketLen > 0)
- memcpy(pszInfo, databuf, wPacketLen);
- pszInfo[wPacketLen] = 0;
-
- ProtoBroadcastAck(NULL, ICQACKTYPE_SMS, ACKRESULT_FAILED, (HANDLE)wCookie, (LPARAM)pszInfo);
- FreeCookie(wCookie);
- }
- break;
-
- case META_SMS_DELIVERY_RECEIPT:
- // Todo: This overlaps with META_SET_AFFINFO_ACK.
- // Todo: Check what happens if result != A
- if (wPacketLen > 8) {
- databuf += 6; // Some unknowns
- wPacketLen -= 6;
-
- size_t wNetworkNameLen, wAckLen;
- unpackWord(&databuf, &wNetworkNameLen);
- if (wPacketLen >= (wNetworkNameLen + 2)) {
- databuf += wNetworkNameLen;
- wPacketLen -= wNetworkNameLen;
-
- unpackWord(&databuf, &wAckLen);
- char *pszInfo = (char*)_alloca(wAckLen + 1);
- // Terminate buffer
- if (wAckLen > 0)
- memcpy(pszInfo, databuf, wAckLen);
- pszInfo[wAckLen] = 0;
-
- ProtoBroadcastAck(NULL, ICQACKTYPE_SMS, ACKRESULT_SENTREQUEST, (HANDLE)wCookie, (LPARAM)pszInfo);
- FreeCookie(wCookie);
-
- // Parsing success
- break;
- }
- }
-
- // Parsing failure
- debugLogA("Error: Failure parsing META_SMS_DELIVERY_RECEIPT");
- break;
-
- case META_DIRECTORY_DATA:
- case META_DIRECTORY_RESPONSE:
- if (bResultCode == 0x0A)
- handleDirectoryQueryResponse(databuf, wPacketLen, wCookie, wReplySubtype, wFlags);
- else
- debugLogA("Error: Directory request failed, code %u", bResultCode);
- break;
-
- case META_DIRECTORY_UPDATE_ACK:
- if (bResultCode == 0x0A)
- handleDirectoryUpdateResponse(databuf, wPacketLen, wCookie);
- else
- debugLogA("Error: Directory request failed, code %u", bResultCode);
- break;
-
- case META_BASIC_USERINFO:
- case META_WORK_USERINFO:
- case META_MORE_USERINFO:
- case META_NOTES_USERINFO:
- case META_EMAIL_USERINFO:
- case META_INTERESTS_USERINFO:
- case META_AFFILATIONS_USERINFO:
- case META_SHORT_USERINFO:
- case META_HPAGECAT_USERINFO:
- debugLogA("Warning: Ignored 15/03 (legacy user info) replysubtype x%x", wReplySubtype);
- break;
-
- default:
- debugLogA("Warning: Ignored 15/03 replysubtype x%x", wReplySubtype);
- break;
- }
-
- // Success
- return;
- }
-
- // Failure
- debugLogA("Warning: Broken 15/03 ExtensionMetaResponse");
-}
-
-void CIcqProto::ReleaseSearchCookie(DWORD dwCookie, cookie_search *pCookie)
-{
- if (pCookie) {
- FreeCookie(dwCookie);
- if (pCookie->dwMainId) {
- if (pCookie->dwStatus) {
- SAFE_FREE((void**)&pCookie);
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0);
- }
- else pCookie->dwStatus = 1;
- }
- else {
- SAFE_FREE((void**)&pCookie);
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0);
- }
- }
- else ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0);
-}
-
-void CIcqProto::parseSearchReplies(unsigned char *databuf, size_t wPacketLen, WORD wCookie, WORD wReplySubtype, BYTE bResultCode)
-{
- BYTE bParsingOK = FALSE; // For debugging purposes only
- BOOL bLastUser = FALSE;
-
- cookie_search *pCookie;
- if (!FindCookie(wCookie, nullptr, (void**)&pCookie)) {
- debugLogA("Warning: Received unexpected search reply");
- pCookie = nullptr;
- }
-
- switch (wReplySubtype) {
- case SRV_LAST_USER_FOUND: // Search: last user found reply
- bLastUser = TRUE;
-
- case SRV_USER_FOUND: // Search: user found reply
- if (bLastUser)
- debugLogA("SNAC(0x15,0x3): Last search reply");
- else
- debugLogA("SNAC(0x15,0x3): Search reply");
-
- if (bResultCode == 0xA) {
- ICQSEARCHRESULT sr = { 0 };
- DWORD dwUin;
- char szUin[UINMAXLEN];
- size_t wLen;
-
- sr.hdr.cbSize = sizeof(sr);
-
- // Remaining bytes
- if (wPacketLen < 2)
- break;
- unpackLEWord(&databuf, &wLen);
- wPacketLen -= 2;
-
- _ASSERTE(wLen <= wPacketLen);
- if (wLen > wPacketLen)
- break;
-
- // Uin
- if (wPacketLen < 4)
- break;
- unpackLEDWord(&databuf, &dwUin); // Uin
- wPacketLen -= 4;
- sr.uin = dwUin;
- _itoa(dwUin, szUin, 10);
- sr.hdr.id.w = (wchar_t*)szUin;
-
- // Nick
- if (wPacketLen < 2)
- break;
- unpackLEWord(&databuf, &wLen);
- wPacketLen -= 2;
- if (wLen > 0) {
- if (wPacketLen < wLen || (databuf[wLen - 1] != 0))
- break;
- sr.hdr.nick.w = (wchar_t*)databuf;
- databuf += wLen;
- }
- else {
- sr.hdr.nick.w = nullptr;
- }
-
- // First name
- if (wPacketLen < 2)
- break;
- unpackLEWord(&databuf, &wLen);
- wPacketLen -= 2;
- if (wLen > 0) {
- if (wPacketLen < wLen || (databuf[wLen - 1] != 0))
- break;
- sr.hdr.firstName.w = (wchar_t*)databuf;
- databuf += wLen;
- }
- else sr.hdr.firstName.w = nullptr;
-
- // Last name
- if (wPacketLen < 2)
- break;
- unpackLEWord(&databuf, &wLen);
- wPacketLen -= 2;
- if (wLen > 0) {
- if (wPacketLen < wLen || (databuf[wLen - 1] != 0))
- break;
- sr.hdr.lastName.w = (wchar_t*)databuf;
- databuf += wLen;
- }
- else sr.hdr.lastName.w = nullptr;
-
- // E-mail name
- if (wPacketLen < 2)
- break;
- unpackLEWord(&databuf, &wLen);
- wPacketLen -= 2;
- if (wLen > 0) {
- if (wPacketLen < wLen || (databuf[wLen - 1] != 0))
- break;
- sr.hdr.email.w = (wchar_t*)databuf;
- databuf += wLen;
- }
- else sr.hdr.email.w = nullptr;
-
- // Authentication needed flag
- if (wPacketLen < 1)
- break;
- unpackByte(&databuf, &sr.auth);
-
- // Finally, broadcast the result
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)wCookie, (LPARAM)&sr);
-
- // Broadcast "Last result" ack if this was the last user found
- if (wReplySubtype == SRV_LAST_USER_FOUND) {
- if (wPacketLen >= 10) {
- DWORD dwLeft;
-
- databuf += 5;
- unpackLEDWord(&databuf, &dwLeft);
- if (dwLeft)
- debugLogA("Warning: %d search results omitted", dwLeft);
- }
- ReleaseSearchCookie(wCookie, pCookie);
- }
- bParsingOK = TRUE;
- }
- else {
- // Failed search
- debugLogA("SNAC(0x15,0x3): Search error %u", bResultCode);
-
- ReleaseSearchCookie(wCookie, pCookie);
-
- bParsingOK = TRUE;
- }
- break;
-
- case SRV_RANDOM_FOUND: // Random search server reply
- default:
- if (pCookie)
- ReleaseCookie(wCookie);
- break;
- }
-
- // For debugging purposes only
- if (!bParsingOK) {
- debugLogA("Warning: Parsing error in 15/03 search reply type x%x", wReplySubtype);
- _ASSERTE(!bParsingOK);
- }
-}
-
-void CIcqProto::parseUserInfoUpdateAck(WORD wCookie, WORD wReplySubtype, BYTE bResultCode)
-{
- switch (wReplySubtype) {
- case META_SET_PASSWORD_ACK: // Set user password server ack
- if (bResultCode == 0xA)
- ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0);
- else
- ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_FAILED, (HANDLE)wCookie, 0);
-
- FreeCookie(wCookie);
- break;
-
- default:
- debugLogA("Warning: Ignored 15/03 user info update ack type x%x", wReplySubtype);
- break;
- }
-}
-
-UserInfoRecordItem rEmail[] =
-{
- { 0x64, DBVT_UTF8, "e-mail%u" }
-};
-
-UserInfoRecordItem rAddress[] =
-{
- { 0x64, DBVT_UTF8, "Street" },
- { 0x6E, DBVT_UTF8, "City" },
- { 0x78, DBVT_UTF8, "State" },
- { 0x82, DBVT_UTF8, "ZIP" },
- { 0x8C, DBVT_WORD, "Country" }
-};
-
-UserInfoRecordItem rOriginAddress[] =
-{
- { 0x64, DBVT_UTF8, "OriginStreet" },
- { 0x6E, DBVT_UTF8, "OriginCity" },
- { 0x78, DBVT_UTF8, "OriginState" },
- { 0x8C, DBVT_WORD, "OriginCountry" }
-};
-
-UserInfoRecordItem rCompany[] =
-{
- { 0x64, DBVT_UTF8, "CompanyPosition" },
- { 0x6E, DBVT_UTF8, "Company" },
- { 0x7D, DBVT_UTF8, "CompanyDepartment" },
- { 0x78, DBVT_UTF8, "CompanyHomepage" },
- { 0x82, DBVT_WORD, "CompanyIndustry" },
- { 0xAA, DBVT_UTF8, "CompanyStreet" },
- { 0xB4, DBVT_UTF8, "CompanyCity" },
- { 0xBE, DBVT_UTF8, "CompanyState" },
- { 0xC8, DBVT_UTF8, "CompanyZIP" },
- { 0xD2, DBVT_WORD, "CompanyCountry" }
-};
-
-UserInfoRecordItem rEducation[] =
-{
- { 0x64, DBVT_WORD, "StudyLevel" },
- { 0x6E, DBVT_UTF8, "StudyInstitute" },
- { 0x78, DBVT_UTF8, "StudyDegree" },
- { 0x8C, DBVT_WORD, "StudyYear" }
-};
-
-UserInfoRecordItem rInterest[] =
-{
- { 0x64, DBVT_UTF8, "Interest%uText" },
- { 0x6E, DBVT_WORD, "Interest%uCat" }
-};
-
-int CIcqProto::parseUserInfoRecord(MCONTACT hContact, oscar_tlv *pData, UserInfoRecordItem pRecordDef[], int nRecordDef, int nMaxRecords)
-{
- int nRecords = 0;
-
- if (pData && pData->wLen >= 2) {
- BYTE *pRecords = pData->pData;
- WORD wRecordCount;
- unpackWord(&pRecords, &wRecordCount);
- oscar_tlv_record_list *cData = readIntoTLVRecordList(&pRecords, pData->wLen - 2, nMaxRecords > wRecordCount ? wRecordCount : nMaxRecords);
- oscar_tlv_record_list *cDataItem = cData;
- while (cDataItem) {
- oscar_tlv_chain *cItem = cDataItem->item;
-
- for (int i = 0; i < nRecordDef; i++) {
- char szItemKey[MAX_PATH];
- mir_snprintf(szItemKey, pRecordDef[i].szDbSetting, nRecords);
-
- switch (pRecordDef[i].dbType) {
- case DBVT_UTF8:
- writeDbInfoSettingTLVStringUtf(hContact, szItemKey, cItem, pRecordDef[i].wTLV);
- break;
-
- case DBVT_WORD:
- writeDbInfoSettingTLVWord(hContact, szItemKey, cItem, pRecordDef[i].wTLV);
- break;
- }
- }
- nRecords++;
-
- cDataItem = cDataItem->next;
- }
- // release memory
- disposeRecordList(&cData);
- }
-
- // remove old data from database
- if (!nRecords || nMaxRecords > 1)
- for (int i = nRecords; i <= nMaxRecords; i++)
- for (int j = 0; j < nRecordDef; j++) {
- char szItemKey[MAX_PATH];
- mir_snprintf(szItemKey, pRecordDef[j].szDbSetting, i);
- delSetting(hContact, szItemKey);
- }
-
- return nRecords;
-}
-
-
-void CIcqProto::handleDirectoryQueryResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie, WORD wReplySubtype, WORD wFlags)
-{
- WORD wBytesRemaining = 0;
- snac_header requestSnac = { 0 };
- BYTE requestResult;
-
- debugLogA("Received directory query response");
-
- if (wPacketLen >= 2)
- unpackLEWord(&databuf, &wBytesRemaining);
- wPacketLen -= 2;
- _ASSERTE(wPacketLen == wBytesRemaining);
-
- if (!unpackSnacHeader(&requestSnac, &databuf, &wPacketLen) || !requestSnac.bValid) {
- debugLogA("Error: Failed to parse directory response");
- return;
- }
-
- cookie_directory_data *pCookieData;
- MCONTACT hContact;
- // check request cookie
- if (!FindCookie(wCookie, &hContact, (void**)&pCookieData) || !pCookieData) {
- debugLogA("Warning: Ignoring unrequested directory reply type (x%x, x%x)", requestSnac.wFamily, requestSnac.wSubtype);
- return;
- }
- /// FIXME: we should really check the snac contents according to cookie data here ??
-
- // Check if this is the last packet for this request
- BOOL bMoreDataFollows = wFlags & 0x0001 && requestSnac.wFlags & 0x0001;
-
- if (wPacketLen >= 3)
- unpackByte(&databuf, &requestResult);
- else {
- debugLogA("Error: Malformed directory response");
- if (!bMoreDataFollows)
- ReleaseCookie(wCookie);
- return;
- }
-
- if (requestResult != 1 && requestResult != 4) {
- debugLogA("Error: Directory request failed, status %u", requestResult);
-
- if (!bMoreDataFollows) {
- if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER)
- ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0);
- else if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH)
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); // should report error here, but Find/Add module does not support that
- ReleaseCookie(wCookie);
- }
- return;
- }
-
- size_t wLen;
- unpackWord(&databuf, &wLen);
- wPacketLen -= 3;
- if (wLen)
- debugLogA("Warning: Data in error message present!");
-
- if (wPacketLen <= 0x16) { // sanity check
- debugLogA("Error: Malformed directory response");
-
- if (!bMoreDataFollows) {
- if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER)
- ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0);
- else if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH)
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); // should report error here, but Find/Add module does not support that
- ReleaseCookie(wCookie);
- }
- return;
- }
- databuf += 0x10; // unknown stuff
- wPacketLen -= 0x10;
-
- DWORD dwItemCount;
- WORD wPageCount;
-
- /// FIXME: check itemcount, pagecount against the cookie data ???
-
- unpackDWord(&databuf, &dwItemCount);
- unpackWord(&databuf, &wPageCount);
- wPacketLen -= 6;
-
- if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH && !bMoreDataFollows)
- debugLogA("Directory Search: %d contacts found (%u pages)", dwItemCount, wPageCount);
-
- if (wPacketLen <= 2) { // sanity check, block expected
- debugLogA("Error: Malformed directory response");
-
- if (!bMoreDataFollows) {
- if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER)
- ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0);
- else if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH)
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); // should report error here, but Find/Add module does not support that
- ReleaseCookie(wCookie);
- }
- return;
- }
-
- WORD wData;
- unpackWord(&databuf, &wData); // This probably the count of items following (a block)
- wPacketLen -= 2;
- if (wPacketLen >= 2 && wData >= 1) {
- unpackWord(&databuf, &wLen); // This is the size of the first item
- wPacketLen -= 2;
- }
-
- if (wData == 0 && pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH) {
- debugLogA("Directory Search: No contacts found");
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0);
- ReleaseCookie(wCookie);
- return;
- }
-
- _ASSERTE(wData == 1 && wPacketLen == wLen);
- if (wData != 1 || wPacketLen != wLen) {
- debugLogA("Error: Malformed directory response (missing data)");
-
- if (!bMoreDataFollows) {
- if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER)
- ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0);
- else if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH)
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); // should report error here, but Find/Add module does not support that
- ReleaseCookie(wCookie);
- }
- return;
- }
-
- oscar_tlv_chain *pDirectoryData = readIntoTLVChain(&databuf, wLen, -1);
- if (pDirectoryData) {
- switch (pCookieData->bRequestType) {
- case DIRECTORYREQUEST_INFOOWNER:
- parseDirectoryUserDetailsData(NULL, pDirectoryData, pCookieData, wReplySubtype);
- break;
-
- case DIRECTORYREQUEST_INFOUSER:
- {
- DWORD dwUin = 0;
- char *szUid = pDirectoryData->getString(0x32, 1);
- if (!szUid) {
- debugLogA("Error: Received unrecognized data from the directory");
- break;
- }
-
- if (IsStringUIN(szUid))
- dwUin = atoi(szUid);
-
- if (hContact != HContactFromUID(dwUin, szUid, nullptr)) {
- debugLogA("Error: Received data does not match cookie contact, ignoring.");
- SAFE_FREE(&szUid);
- break;
- }
- else SAFE_FREE(&szUid);
- }
-
- case DIRECTORYREQUEST_INFOMULTI:
- parseDirectoryUserDetailsData(hContact, pDirectoryData, pCookieData, wReplySubtype);
- break;
-
- case DIRECTORYREQUEST_SEARCH:
- parseDirectorySearchData(pDirectoryData, wCookie, wReplySubtype);
- break;
-
- default:
- debugLogA("Error: Unknown cookie type %x for directory response!", pCookieData->bRequestType);
- }
- disposeChain(&pDirectoryData);
- }
- else debugLogA("Error: Failed parsing directory response");
-
- // Release Memory
- if (!bMoreDataFollows)
- ReleaseCookie(wCookie);
-}
-
-static int calcAgeFromBirthDate(double dDate)
-{
- if (dDate > 0) { // date is stored as double with unit equal to a day, incrementing since 1/1/1900 0:00 GMT
- SYSTEMTIME sDate = { 0 };
- if (VariantTimeToSystemTime(dDate + 2, &sDate)) {
- SYSTEMTIME sToday = { 0 };
- GetLocalTime(&sToday);
-
- int nAge = sToday.wYear - sDate.wYear;
- if (sToday.wMonth < sDate.wMonth || (sToday.wMonth == sDate.wMonth && sToday.wDay < sDate.wDay))
- nAge--;
-
- return nAge;
- }
- }
- return 0;
-}
-
-void CIcqProto::parseDirectoryUserDetailsData(MCONTACT hContact, oscar_tlv_chain *cDetails, cookie_directory_data *pCookieData, WORD wReplySubType)
-{
- if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOMULTI && !hContact) {
- DWORD dwUin = 0;
- char *szUid = cDetails->getString(0x32, 1);
- if (!szUid) {
- debugLogA("Error: Received unrecognized data from the directory");
- return;
- }
-
- if (IsStringUIN(szUid))
- dwUin = atoi(szUid);
-
- hContact = HContactFromUID(dwUin, szUid, nullptr);
- if (hContact == INVALID_CONTACT_ID) {
- debugLogA("Error: Received details for unknown contact \"%s\"", szUid);
- SAFE_FREE(&szUid);
- return;
- }
-
- debugLogA("Received user info for %s from directory", szUid);
- SAFE_FREE(&szUid);
- }
-
- oscar_tlv *pTLV = cDetails->getTLV(0x50, 1);
- if (pTLV && pTLV->wLen > 0)
- writeDbInfoSettingTLVStringUtf(hContact, "e-mail", cDetails, 0x50); // Verified e-mail
- else
- writeDbInfoSettingTLVStringUtf(hContact, "e-mail", cDetails, 0x55); // Pending e-mail
-
- writeDbInfoSettingTLVStringUtf(hContact, "FirstName", cDetails, 0x64);
- writeDbInfoSettingTLVStringUtf(hContact, "LastName", cDetails, 0x6E);
- writeDbInfoSettingTLVStringUtf(hContact, "Nick", cDetails, 0x78);
- // Home Address
- parseUserInfoRecord(hContact, cDetails->getTLV(0x96, 1), rAddress, _countof(rAddress), 1);
- // Origin Address
- parseUserInfoRecord(hContact, cDetails->getTLV(0xA0, 1), rOriginAddress, _countof(rOriginAddress), 1);
- // Phones
- pTLV = cDetails->getTLV(0xC8, 1);
- if (pTLV && pTLV->wLen >= 2) {
- BYTE *pRecords = pTLV->pData;
- WORD wRecordCount;
- unpackWord(&pRecords, &wRecordCount);
- oscar_tlv_record_list *cPhones = readIntoTLVRecordList(&pRecords, pTLV->wLen - 2, wRecordCount);
- if (cPhones) {
- oscar_tlv_chain *cPhone;
- cPhone = cPhones->getRecordByTLV(0x6E, 1);
- writeDbInfoSettingTLVStringUtf(hContact, "Phone", cPhone, 0x64);
- cPhone = cPhones->getRecordByTLV(0x6E, 2);
- writeDbInfoSettingTLVStringUtf(hContact, "CompanyPhone", cPhone, 0x64);
- cPhone = cPhones->getRecordByTLV(0x6E, 3);
- writeDbInfoSettingTLVStringUtf(hContact, "Cellular", cPhone, 0x64);
- cPhone = cPhones->getRecordByTLV(0x6E, 4);
- writeDbInfoSettingTLVStringUtf(hContact, "Fax", cPhone, 0x64);
- cPhone = cPhones->getRecordByTLV(0x6E, 5);
- writeDbInfoSettingTLVStringUtf(hContact, "CompanyFax", cPhone, 0x64);
-
- disposeRecordList(&cPhones);
- }
- else { // Remove old data when phones not available
- delSetting(hContact, "Phone");
- delSetting(hContact, "CompanyPhone");
- delSetting(hContact, "Cellular");
- delSetting(hContact, "Fax");
- delSetting(hContact, "CompanyFax");
- }
- }
- else { // Remove old data when phones not available
- delSetting(hContact, "Phone");
- delSetting(hContact, "CompanyPhone");
- delSetting(hContact, "Cellular");
- delSetting(hContact, "Fax");
- delSetting(hContact, "CompanyFax");
- }
- // Emails
- parseUserInfoRecord(hContact, cDetails->getTLV(0x8C, 1), rEmail, _countof(rEmail), 4);
-
- writeDbInfoSettingTLVByte(hContact, "Timezone", cDetails, 0x17C);
- // Company
- parseUserInfoRecord(hContact, cDetails->getTLV(0x118, 1), rCompany, _countof(rCompany), 1);
- // Education
- parseUserInfoRecord(hContact, cDetails->getTLV(0x10E, 1), rEducation, _countof(rEducation), 1);
-
- switch (cDetails->getNumber(0x82, 1)) {
- case 1:
- setByte(hContact, "Gender", 'F');
- break;
- case 2:
- setByte(hContact, "Gender", 'M');
- break;
- default:
- delSetting(hContact, "Gender");
- }
-
- writeDbInfoSettingTLVStringUtf(hContact, "Homepage", cDetails, 0xFA);
- writeDbInfoSettingTLVDate(hContact, "BirthYear", "BirthMonth", "BirthDay", cDetails, 0x1A4);
-
- writeDbInfoSettingTLVByte(hContact, "Language1", cDetails, 0xAA);
- writeDbInfoSettingTLVByte(hContact, "Language2", cDetails, 0xB4);
- writeDbInfoSettingTLVByte(hContact, "Language3", cDetails, 0xBE);
-
- writeDbInfoSettingTLVByte(hContact, "MaritalStatus", cDetails, 0x12C);
- // Interests
- parseUserInfoRecord(hContact, cDetails->getTLV(0x122, 1), rInterest, _countof(rInterest), 4);
-
- writeDbInfoSettingTLVStringUtf(hContact, "About", cDetails, 0x186);
-
- // if (hContact)
- // writeDbInfoSettingTLVStringUtf(hContact, DBSETTING_STATUS_NOTE, cDetails, 0x226);
- // else
- if (!hContact) { // Owner contact needs special processing, in the database is current status note for the client
- // We just received the last status note set on directory, if it differs call SetStatusNote() to
- // ensure the directory will be updated (it should be in process anyway)
- char *szClientStatusNote = getSettingStringUtf(hContact, DBSETTING_STATUS_NOTE, nullptr);
- char *szDirectoryStatusNote = cDetails->getString(0x226, 1);
-
- if (mir_strcmp(szClientStatusNote, szDirectoryStatusNote))
- SetStatusNote(szClientStatusNote, 1000, TRUE);
-
- // Release memory
- SAFE_FREE(&szDirectoryStatusNote);
- SAFE_FREE(&szClientStatusNote);
- }
-
- writeDbInfoSettingTLVByte(hContact, "PrivacyLevel", cDetails, 0x1F9);
-
- if (!hContact) {
- setByte(hContact, "Auth", !cDetails->getByte(0x19A, 1));
- writeDbInfoSettingTLVByte(hContact, "WebAware", cDetails, 0x212);
- writeDbInfoSettingTLVByte(hContact, "AllowSpam", cDetails, 0x1EA);
- }
-
- writeDbInfoSettingTLVWord(hContact, "InfoCP", cDetails, 0x1C2);
-
- if (hContact) { // Handle deprecated setting (Age & Birthdate are not separate fields anymore)
- int nAge = calcAgeFromBirthDate(cDetails->getDouble(0x1A4, 1));
-
- if (nAge)
- setWord(hContact, "Age", nAge);
- else
- delSetting(hContact, "Age");
- }
- else // we do not need to calculate age for owner
- delSetting(hContact, "Age");
-
- { // Save user info last update time and privacy token
- double dInfoTime;
- BYTE pbEmptyMetaToken[0x10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int bHasMetaToken = FALSE;
-
- // Check if the details arrived with privacy token!
- if ((pTLV = cDetails->getTLV(0x3C, 1)) && pTLV->wLen == 0x10 && memcmp(pTLV->pData, pbEmptyMetaToken, 0x10))
- bHasMetaToken = TRUE;
-
- // !Important, we need to save the MDir server-item time - it can be newer than the one from the directory
- if ((dInfoTime = getSettingDouble(hContact, DBSETTING_METAINFO_TIME, 0)) > 0)
- setSettingDouble(hContact, DBSETTING_METAINFO_SAVED, dInfoTime);
- else if (bHasMetaToken || !hContact)
- writeDbInfoSettingTLVDouble(hContact, DBSETTING_METAINFO_SAVED, cDetails, 0x1CC);
- else
- setDword(hContact, DBSETTING_METAINFO_SAVED, time(0));
- }
-
- if (wReplySubType == META_DIRECTORY_RESPONSE)
- if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER)
- ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)1, 0);
-
- // Remove user from info update queue. Removing is fast so we always call this
- // even if it is likely that the user is not queued at all.
- if (hContact)
- icq_DequeueUser(getContactUin(hContact));
-}
-
-
-void CIcqProto::parseDirectorySearchData(oscar_tlv_chain *cDetails, DWORD dwCookie, WORD wReplySubType)
-{
- char *szUid = cDetails->getString(0x32, 1); // User ID
-
- debugLogA("Directory Search: Found user %s", szUid);
-
- ICQSEARCHRESULT isr = { 0 };
- isr.hdr.cbSize = sizeof(ICQSEARCHRESULT);
- isr.hdr.flags = PSR_UTF8;
- isr.hdr.id.a = szUid;
-
- if (IsStringUIN(szUid))
- isr.uin = atoi(szUid);
- else
- isr.uin = 0;
-
- oscar_tlv *pTLV = cDetails->getTLV(0x50, 1);
- char *szData = nullptr;
-
- if (pTLV && pTLV->wLen > 0)
- szData = cDetails->getString(0x50, 1); // Verified e-mail
- else
- szData = cDetails->getString(0x55, 1); // Pending e-mail
- if (szData != nullptr)
- isr.hdr.email.a = szData;
-
- szData = cDetails->getString(0x64, 1); // First Name
- if (szData != nullptr)
- isr.hdr.firstName.a = szData;
-
- szData = cDetails->getString(0x6E, 1); // Last Name
- if (szData != nullptr)
- isr.hdr.lastName.a = szData;
-
- szData = cDetails->getString(0x78, 1); // Nick
- if (szData != nullptr)
- isr.hdr.nick.a = szData;
-
- switch (cDetails->getNumber(0x82, 1)) { // Gender
- case 1:
- isr.gender = 'F';
- break;
- case 2:
- isr.gender = 'M';
- break;
- }
-
- pTLV = cDetails->getTLV(0x96, 1);
- if (pTLV && pTLV->wLen >= 4) {
- BYTE *buf = pTLV->pData;
- oscar_tlv_chain *chain = readIntoTLVChain(&buf, pTLV->wLen, 0);
- if (chain)
- isr.country = chain->getDWord(0x8C, 1); // Home Country
- disposeChain(&chain);
- }
-
- isr.auth = !cDetails->getByte(0x19A, 1); // Require Authorization
- isr.maritalStatus = cDetails->getNumber(0x12C, 1); // Marital Status
-
- // calculate Age if Birthdate is available
- isr.age = calcAgeFromBirthDate(cDetails->getDouble(0x1A4, 1));
-
- // Finally, broadcast the result
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)dwCookie, (LPARAM)&isr);
-
- // Release memory
- SAFE_FREE(&isr.hdr.id.a);
- SAFE_FREE(&isr.hdr.nick.a);
- SAFE_FREE(&isr.hdr.firstName.a);
- SAFE_FREE(&isr.hdr.lastName.a);
- SAFE_FREE(&isr.hdr.email.a);
-
- // Search is over, broadcast final ack
- if (wReplySubType == META_DIRECTORY_RESPONSE)
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0);
-}
-
-
-void CIcqProto::handleDirectoryUpdateResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie)
-{
- WORD wBytesRemaining = 0;
- snac_header requestSnac = { 0 };
- BYTE requestResult;
-
- debugLogA("Received directory update response");
-
- if (wPacketLen >= 2)
- unpackLEWord(&databuf, &wBytesRemaining);
- wPacketLen -= 2;
- _ASSERTE(wPacketLen == wBytesRemaining);
-
- if (!unpackSnacHeader(&requestSnac, &databuf, &wPacketLen) || !requestSnac.bValid) {
- debugLogA("Error: Failed to parse directory response");
- return;
- }
-
- cookie_directory_data *pCookieData;
- MCONTACT hContact;
- // check request cookie
- if (!FindCookie(wCookie, &hContact, (void**)&pCookieData) || !pCookieData) {
- debugLogA("Warning: Ignoring unrequested directory reply type (x%x, x%x)", requestSnac.wFamily, requestSnac.wSubtype);
- return;
- }
- /// FIXME: we should really check the snac contents according to cookie data here ??
-
- if (wPacketLen >= 3)
- unpackByte(&databuf, &requestResult);
- else {
- debugLogA("Error: Malformed directory response");
- ReleaseCookie(wCookie);
- return;
- }
- if (requestResult != 1 && requestResult != 4) {
- debugLogA("Error: Directory request failed, status %u", requestResult);
-
- if (pCookieData->bRequestType == DIRECTORYREQUEST_UPDATEOWNER)
- ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_FAILED, (HANDLE)wCookie, 0);
-
- ReleaseCookie(wCookie);
- return;
- }
- size_t wLen;
-
- unpackWord(&databuf, &wLen);
- wPacketLen -= 3;
- if (wLen)
- debugLogA("Warning: Data in error message present!");
-
- if (pCookieData->bRequestType == DIRECTORYREQUEST_UPDATEOWNER)
- ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0);
- if (wPacketLen == 0x18) {
- DWORD64 qwMetaTime;
- BYTE pbEmptyMetaToken[0x10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- unpackQWord(&databuf, &qwMetaTime);
- setSettingBlob(NULL, DBSETTING_METAINFO_TIME, (BYTE*)&qwMetaTime, 8);
-
- if (memcmp(databuf, pbEmptyMetaToken, 0x10))
- setSettingBlob(NULL, DBSETTING_METAINFO_TOKEN, databuf, 0x10);
- }
- ReleaseCookie(wCookie);
-}
diff --git a/protocols/IcqOscarJ/src/fam_17signon.cpp b/protocols/IcqOscarJ/src/fam_17signon.cpp
deleted file mode 100644
index b4bc11a249..0000000000
--- a/protocols/IcqOscarJ/src/fam_17signon.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleAuthorizationFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info)
-{
- switch (pSnacHeader->wSubtype) {
-
- case ICQ_SIGNON_ERROR:
- {
- WORD wError;
-
- if (wBufferLength >= 2)
- unpackWord(&pBuffer, &wError);
- else
- wError = 0;
-
- LogFamilyError(ICQ_AUTHORIZATION_FAMILY, wError);
- break;
- }
-
- case ICQ_SIGNON_AUTH_KEY:
- handleAuthKeyResponse(pBuffer, wBufferLength, info);
- break;
-
- case ICQ_SIGNON_LOGIN_REPLY:
- handleLoginReply(pBuffer, wBufferLength, info);
- break;
-
- default:
- debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_AUTHORIZATION_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-static void icq_encryptPassword(const char *szPassword, BYTE *encrypted)
-{
- BYTE table[] =
- {
- 0xf3, 0x26, 0x81, 0xc4,
- 0x39, 0x86, 0xdb, 0x92,
- 0x71, 0xa3, 0xb9, 0xe6,
- 0x53, 0x7a, 0x95, 0x7c
- };
-
- for (int i = 0; szPassword[i]; i++)
- encrypted[i] = (szPassword[i] ^ table[i % 16]);
-}
-
-void CIcqProto::sendClientAuth(const char *szKey, size_t wKeyLen, BOOL bSecure)
-{
- char szUin[UINMAXLEN];
- icq_packet packet;
-
- size_t wUinLen = mir_strlen(strUID(m_dwLocalUIN, szUin));
-
- packet.wLen = WORD((m_bLegacyFix ? 65 : 70) + sizeof(CLIENT_ID_STRING) + wUinLen + wKeyLen + (m_bSecureConnection ? 4 : 0));
-
- if (bSecure) {
- serverPacketInit(&packet, packet.wLen + 10);
- packFNACHeader(&packet, ICQ_AUTHORIZATION_FAMILY, ICQ_SIGNON_LOGIN_REQUEST, 0, 0);
- }
- else {
- write_flap(&packet, ICQ_LOGIN_CHAN);
- packDWord(&packet, 0x00000001);
- }
- packTLV(&packet, 0x0001, wUinLen, (LPBYTE)szUin);
-
- if (bSecure) { // Pack MD5 auth digest
- packTLV(&packet, 0x0025, wKeyLen, (BYTE*)szKey);
- packDWord(&packet, 0x004C0000); // empty TLV(0x4C): unknown
- }
- else { // Pack old style password hash
- BYTE hash[20];
-
- icq_encryptPassword(szKey, hash);
- packTLV(&packet, 0x0002, wKeyLen, hash);
- }
-
- // Pack client identification details.
- packTLV(&packet, 0x0003, (WORD)sizeof(CLIENT_ID_STRING) - 1, (LPBYTE)CLIENT_ID_STRING);
- packTLVWord(&packet, 0x0017, CLIENT_VERSION_MAJOR);
- packTLVWord(&packet, 0x0018, CLIENT_VERSION_MINOR);
- packTLVWord(&packet, 0x0019, CLIENT_VERSION_LESSER);
- packTLVWord(&packet, 0x001a, CLIENT_VERSION_BUILD);
- packTLVWord(&packet, 0x0016, CLIENT_ID_CODE);
- packTLVDWord(&packet, 0x0014, CLIENT_DISTRIBUTION);
- packTLV(&packet, 0x000f, 0x0002, (LPBYTE)CLIENT_LANGUAGE);
- packTLV(&packet, 0x000e, 0x0002, (LPBYTE)CLIENT_COUNTRY);
- if (!m_bLegacyFix)
- packTLV(&packet, 0x0094, 0x0001, &m_bConnectionLost); // CLIENT_RECONNECT flag
- if (m_bSecureConnection)
- packDWord(&packet, 0x008C0000); // empty TLV(0x8C): use SSL
-
- sendServPacket(&packet);
-}
-
-void CIcqProto::handleAuthKeyResponse(BYTE *buf, size_t wPacketLen, serverthread_info *info)
-{
- char szKey[64] = { 0 };
- mir_md5_state_t state;
- BYTE digest[16];
-
- debugLogA("Received %s", "ICQ_SIGNON_AUTH_KEY");
-
- if (wPacketLen < 2) {
- debugLogA("Malformed %s", "ICQ_SIGNON_AUTH_KEY");
- icq_LogMessage(LOG_FATAL, LPGEN("Secure login failed.\nInvalid server response."));
- SetCurrentStatus(ID_STATUS_OFFLINE);
- return;
- }
-
- size_t wKeyLen;
- unpackWord(&buf, &wKeyLen);
- wPacketLen -= 2;
-
- if (!wKeyLen || wKeyLen > wPacketLen || wKeyLen > sizeof(szKey)) {
- debugLogA("Invalid length in %s: %u", "ICQ_SIGNON_AUTH_KEY", wKeyLen);
- icq_LogMessage(LOG_FATAL, LPGEN("Secure login failed.\nInvalid key length."));
- SetCurrentStatus(ID_STATUS_OFFLINE);
- return;
- }
-
- unpackString(&buf, szKey, wKeyLen);
-
- mir_md5_init(&state);
- mir_md5_append(&state, info->szAuthKey, (int)info->wAuthKeyLen);
- mir_md5_finish(&state, digest);
-
- mir_md5_init(&state);
- mir_md5_append(&state, (LPBYTE)szKey, (int)wKeyLen);
- mir_md5_append(&state, digest, 16);
- mir_md5_append(&state, (LPBYTE)CLIENT_MD5_STRING, sizeof(CLIENT_MD5_STRING) - 1);
- mir_md5_finish(&state, digest);
-
- debugLogA("Sending ICQ_SIGNON_LOGIN_REQUEST to login server");
- sendClientAuth((char*)digest, 0x10, TRUE);
-}
diff --git a/protocols/IcqOscarJ/src/families.h b/protocols/IcqOscarJ/src/families.h
deleted file mode 100644
index 7ca934ab1c..0000000000
--- a/protocols/IcqOscarJ/src/families.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Declaration for handlers of Channel 2 SNAC Families
-// -----------------------------------------------------------------------------
-
-#ifndef __FAMILIES_H
-#define __FAMILIES_H
-
-struct message_ack_params
-{
- BYTE bType;
- DWORD dwUin;
- DWORD dwMsgID1;
- DWORD dwMsgID2;
- directconnect *pDC;
- WORD wCookie;
- int msgType;
- BYTE bFlags;
-};
-
-#define MAT_SERVER_ADVANCED 0
-#define MAT_DIRECT 1
-
-
-/* handleMessageTypes(): mMsgFlags constants */
-#define MTF_DIRECT 1
-#define MTF_PLUGIN 2
-#define MTF_STATUS_EXTENDED 4
-
-
-struct UserInfoRecordItem
-{
- WORD wTLV;
- int dbType;
- char *szDbSetting;
-};
-
-/*---------* Functions *---------------*/
-
-int getPluginTypeIdLen(int nTypeID);
-void packPluginTypeId(icq_packet *packet, int nTypeID);
-
-#define BUL_ALLCONTACTS 0
-#define BUL_VISIBLE 1
-#define BUL_INVISIBLE 2
-#define BUL_TEMPVISIBLE 4
-
-
-#endif /* __FAMILIES_H */
diff --git a/protocols/IcqOscarJ/src/globals.h b/protocols/IcqOscarJ/src/globals.h
deleted file mode 100644
index 84769644c9..0000000000
--- a/protocols/IcqOscarJ/src/globals.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Contains global types & variables declarations.
-//
-// -----------------------------------------------------------------------------
-
-#ifndef __GLOBALS_H
-#define __GLOBALS_H
-
-
-typedef char uid_str[MAX_PATH];
-
-// from init.cpp
-extern DWORD MIRANDA_VERSION;
-
-extern HANDLE hExtraXStatus;
-
-extern const int moodXStatus[];
-
-// from fam_04message.cpp
-struct icq_mode_messages
-{
- char *szOnline;
- char *szAway;
- char *szNa;
- char *szDnd;
- char *szOccupied;
- char *szFfc;
-};
-
-void g_MenuInit();
-void g_MenuUninit();
-
-#endif /* __GLOBALS_H */
diff --git a/protocols/IcqOscarJ/src/guids.h b/protocols/IcqOscarJ/src/guids.h
deleted file mode 100644
index 7c5ba90686..0000000000
--- a/protocols/IcqOscarJ/src/guids.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Contains helper functions to handle oscar message GUIDs.
-// -----------------------------------------------------------------------------
-
-#ifndef __GUIDS_H
-#define __GUIDS_H
-
-typedef DWORD plugin_guid[4];
-
-// Message Capability GUIDs
-static const plugin_guid MCAP_SRV_RELAY_FMT = { MCAP_SRV_RELAY_FMT_s };
-static const plugin_guid MCAP_REVERSE_DC_REQ = { MCAP_REVERSE_DC_REQ_s };
-static const plugin_guid MCAP_FILE_TRANSFER = { MCAP_FILE_TRANSFER_s };
-static const plugin_guid MCAP_CONTACTS = { MCAP_CONTACTS_s };
-
-// Plugin GUIDs
-static const plugin_guid PSIG_MESSAGE = { PSIG_MESSAGE_s };
-static const plugin_guid PSIG_INFO_PLUGIN = { PSIG_INFO_PLUGIN_s };
-static const plugin_guid PSIG_STATUS_PLUGIN = { PSIG_STATUS_PLUGIN_s };
-
-// Plugin Message GUIDs
-static const plugin_guid PMSG_QUERY_INFO = { PMSG_QUERY_INFO_s };
-static const plugin_guid PMSG_QUERY_STATUS = { PMSG_QUERY_STATUS_s };
-
-// Message GUIDs
-static const plugin_guid MGTYPE_MESSAGE = { MGTYPE_MESSAGE_s };
-static const plugin_guid MGTYPE_STATUSMSGEXT = { MGTYPE_STATUSMSGEXT_s };
-static const plugin_guid MGTYPE_FILE = { MGTYPE_FILE_s };
-static const plugin_guid MGTYPE_WEBURL = { MGTYPE_WEBURL_s };
-static const plugin_guid MGTYPE_CONTACTS = { MGTYPE_CONTACTS_s };
-static const plugin_guid MGTYPE_GREETING_CARD = { MGTYPE_GREETING_CARD_s };
-static const plugin_guid MGTYPE_CHAT = { MGTYPE_CHAT_s };
-static const plugin_guid MGTYPE_SMS_MESSAGE = { MGTYPE_SMS_MESSAGE_s };
-static const plugin_guid MGTYPE_XTRAZ_SCRIPT = { MGTYPE_XTRAZ_SCRIPT_s };
-
-// make GUID checks easy
-__forceinline bool CompareGUIDs(DWORD q1, DWORD q2, DWORD q3, DWORD q4, const plugin_guid guid)
-{
- return ((q1 == guid[0]) && (q2 == guid[1]) && (q3 == guid[2]) && (q4 == guid[3])) ? true : false;
-}
-
-// pack entire GUID into icq packet
-static __inline void packGUID(icq_packet *packet, const plugin_guid guid)
-{
- packDWord(packet, guid[0]);
- packDWord(packet, guid[1]);
- packDWord(packet, guid[2]);
- packDWord(packet, guid[3]);
-}
-
-#endif /* __GUIDS_H */
diff --git a/protocols/IcqOscarJ/src/i18n.cpp b/protocols/IcqOscarJ/src/i18n.cpp
deleted file mode 100644
index 76fdf8a09c..0000000000
--- a/protocols/IcqOscarJ/src/i18n.cpp
+++ /dev/null
@@ -1,499 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Contains helper functions to convert text messages between different
-// character sets.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-static BOOL bHasCP_UTF8 = FALSE;
-
-void InitI18N(void)
-{
- CPINFO CPInfo;
- bHasCP_UTF8 = GetCPInfo(CP_UTF8, &CPInfo);
-}
-
-// Returns true if the buffer only contains 7-bit characters.
-BOOL __stdcall IsUSASCII(const char *pBuffer, size_t nSize)
-{
- for (size_t nIndex = 0; nIndex < nSize; nIndex++)
- if (BYTE(pBuffer[nIndex]) > 0x7F)
- return FALSE;
-
- return TRUE;
-}
-
-// Returns true if the unicode buffer only contains 7-bit characters.
-BOOL __stdcall IsUnicodeAscii(const WCHAR *pBuffer, size_t nSize)
-{
- for (size_t nIndex = 0; nIndex < nSize; nIndex++)
- if (WORD(pBuffer[nIndex]) > 0x7F)
- return FALSE;
-
- return TRUE;
-}
-
-
-// Scans a string encoded in UTF-8 to verify that it contains
-// only valid sequences. It will return 1 if the string contains
-// only legitimate encoding sequences; otherwise it will return 0;
-// From 'Secure Programming Cookbook', John Viega & Matt Messier, 2003
-int __stdcall UTF8_IsValid(const char *pszInput)
-{
- int nb;
- if (!pszInput)
- return 0;
-
- for (BYTE* c = (BYTE*)pszInput; *c; c += (nb + 1)) {
- if (!(*c & 0x80))
- nb = 0;
- else if ((*c & 0xc0) == 0x80) return 0;
- else if ((*c & 0xe0) == 0xc0) nb = 1;
- else if ((*c & 0xf0) == 0xe0) nb = 2;
- else if ((*c & 0xf8) == 0xf0) nb = 3;
- else if ((*c & 0xfc) == 0xf8) nb = 4;
- else if ((*c & 0xfe) == 0xfc) nb = 5;
- else nb = 0;
-
- for (int i = 1; i <= nb; i++) // we this forward, do not cross end of string
- if ((*(c + i) & 0xc0) != 0x80)
- return 0;
- }
-
- return 1;
-}
-
-
-int __stdcall get_utf8_size(const WCHAR *unicode)
-{
- int size = 0;
- int index = 0;
- /* calculate the size of the utf-8 string */
- WCHAR c = unicode[index++];
- while (c) {
- if (c < 0x0080)
- size += 1;
- else if (c < 0x0800)
- size += 2;
- else
- size += 3;
- c = unicode[index++];
- }
- return size;
-}
-
-
-// returns ansi string in all cases
-char* __stdcall detect_decode_utf8(const char *from)
-{
- char *temp = nullptr;
-
- if (IsUSASCII(from, mir_strlen(from)) || !UTF8_IsValid(from) || !utf8_decode(from, &temp)) return (char*)from;
- SAFE_FREE((void**)&from);
-
- return temp;
-}
-
-
-/*
-* The following UTF8 routines are
-*
-* Copyright (C) 2001 Peter Harris <peter.harris@hummingbird.com>
-* Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
-*
-* under a GPL license
-*
-* --------------------------------------------------------------
-* Convert a string between UTF-8 and the locale's charset.
-* Invalid bytes are replaced by '#', and characters that are
-* not available in the target encoding are replaced by '?'.
-*
-* If the locale's charset is not set explicitly then it is
-* obtained using nl_langinfo(CODESET), where available, the
-* environment variable CHARSET, or assumed to be US-ASCII.
-*
-* Return value of conversion functions:
-*
-* -1 : memory allocation failed
-* 0 : data was converted exactly
-* 1 : valid data was converted approximately (using '?')
-* 2 : input was invalid (but still converted, using '#')
-* 3 : unknown encoding (but still converted, using '?')
-*/
-
-
-
-/*
-* Convert a string between UTF-8 and the locale's charset.
-*/
-char* __stdcall make_utf8_string_static(const WCHAR *unicode, char *utf8, size_t utf_size)
-{
- int index = 0;
- unsigned int out_index = 0;
- unsigned short c;
-
- c = unicode[index++];
- while (c) {
- if (c < 0x080) {
- if (out_index + 1 >= utf_size) break;
- utf8[out_index++] = (unsigned char)c;
- }
- else if (c < 0x800) {
- if (out_index + 2 >= utf_size) break;
- utf8[out_index++] = 0xc0 | (c >> 6);
- utf8[out_index++] = 0x80 | (c & 0x3f);
- }
- else {
- if (out_index + 3 >= utf_size) break;
- utf8[out_index++] = 0xe0 | (c >> 12);
- utf8[out_index++] = 0x80 | ((c >> 6) & 0x3f);
- utf8[out_index++] = 0x80 | (c & 0x3f);
- }
- c = unicode[index++];
- }
- utf8[out_index] = 0x00;
-
- return utf8;
-}
-
-
-char* __stdcall make_utf8_string(const WCHAR *unicode)
-{
- if (!unicode) return nullptr;
-
- /* first calculate the size of the target string */
- size_t size = get_utf8_size(unicode);
-
- char *out = (char*)SAFE_MALLOC(size + 1);
- if (!out)
- return nullptr;
-
- return make_utf8_string_static(unicode, out, size + 1);
-}
-
-
-WCHAR* __stdcall make_unicode_string_static(const char *utf8, WCHAR *unicode, size_t unicode_size)
-{
- unsigned int out_index = 0;
-
- if (utf8) {
- unsigned int index = 0;
- unsigned char c = utf8[index++];
-
- while (c) {
- if (out_index + 1 >= unicode_size) break;
- if ((c & 0x80) == 0) {
- unicode[out_index++] = c;
- }
- else if ((c & 0xe0) == 0xe0) {
- unicode[out_index] = (c & 0x1F) << 12;
- c = utf8[index++];
- unicode[out_index] |= (c & 0x3F) << 6;
- c = utf8[index++];
- unicode[out_index++] |= (c & 0x3F);
- }
- else {
- unicode[out_index] = (c & 0x3F) << 6;
- c = utf8[index++];
- unicode[out_index++] |= (c & 0x3F);
- }
- c = utf8[index++];
- }
- }
- unicode[out_index] = 0;
-
- return unicode;
-}
-
-
-WCHAR* __stdcall make_unicode_string(const char *utf8)
-{
- int size = 0, index = 0;
-
- if (!utf8) return nullptr;
-
- /* first calculate the size of the target string */
- unsigned char c = utf8[index++];
- while (c) {
- if ((c & 0x80) == 0) {
- index += 0;
- }
- else if ((c & 0xe0) == 0xe0) {
- index += 2;
- }
- else {
- index += 1;
- }
- size += 1;
- c = utf8[index++];
- }
-
- WCHAR *out = (WCHAR*)SAFE_MALLOC((size + 1) * sizeof(WCHAR));
- if (!out)
- return nullptr;
- else
- return make_unicode_string_static(utf8, out, size + 1);
-}
-
-
-int __stdcall utf8_encode(const char *from, char **to)
-{
- int wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, (int)mir_strlen(from), nullptr, 0);
-
- if (wchars == 0) {
-#ifdef _DEBUG
- fprintf(stderr, "Unicode translation error %d\n", GetLastError());
-#endif
- return -1;
- }
-
- WCHAR *unicode = (WCHAR*)_alloca((wchars + 1) * sizeof(WCHAR));
- memset(unicode, 0, ((wchars + 1) * sizeof(WCHAR)));
-
- int err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, (int)mir_strlen(from), unicode, wchars);
- if (err != wchars) {
-#ifdef _DEBUG
- fprintf(stderr, "Unicode translation error %d\n", GetLastError());
-#endif
- return -1;
- }
-
- /* On NT-based windows systems, we could use WideCharToMultiByte(), but
- * MS doesn't actually have a consistent API across win32.
- */
- *to = make_utf8_string(unicode);
- return 0;
-}
-
-
-char* __stdcall ansi_to_utf8(const char *ansi)
-{
- char *szUtf = nullptr;
-
- if (mir_strlen(ansi)) {
- utf8_encode(ansi, &szUtf);
- return szUtf;
- }
-
- return null_strdup("");
-}
-
-
-char* __stdcall ansi_to_utf8_codepage(const char *ansi, WORD wCp)
-{
- size_t wchars = mir_strlen(ansi);
- WCHAR *unicode = (WCHAR*)_alloca((wchars + 1) * sizeof(WCHAR));
- memset(unicode, 0, ((wchars + 1) * sizeof(WCHAR)));
-
- MultiByteToWideChar(wCp, MB_PRECOMPOSED, ansi, (int)wchars, unicode, (int)wchars);
-
- return make_utf8_string(unicode);
-}
-
-
-// Returns 0 on error, 1 on success
-int __stdcall utf8_decode_codepage(const char *from, char **to, WORD wCp)
-{
- int nResult = 0;
-
- _ASSERTE(!(*to)); // You passed a non-zero pointer, make sure it doesnt point to unfreed memory
-
- // Validate the string
- if (!UTF8_IsValid(from))
- return 0;
-
- // Use the native conversion routines when available
- if (bHasCP_UTF8) {
- size_t inlen = mir_strlen(from) + 1;
- WCHAR *wszTemp = (WCHAR *)_alloca(inlen * sizeof(WCHAR));
- memset(wszTemp, 0, (inlen * sizeof(WCHAR)));
-
- // Convert the UTF-8 string to UCS
- if (MultiByteToWideChar(CP_UTF8, 0, from, -1, wszTemp, (int)inlen)) {
- // Convert the UCS string to local ANSI codepage
- *to = (char*)SAFE_MALLOC(inlen);
- if (WideCharToMultiByte(wCp, 0, wszTemp, -1, *to, (int)inlen, nullptr, nullptr)) {
- nResult = 1;
- }
- else {
- SAFE_FREE(to);
- }
- }
- }
- else {
- size_t chars = mir_strlen(from) + 1;
- WCHAR *unicode = (WCHAR*)_alloca(chars * sizeof(WCHAR));
- make_unicode_string_static(from, unicode, chars);
-
- chars = WideCharToMultiByte(wCp, WC_COMPOSITECHECK, unicode, -1, nullptr, 0, nullptr, nullptr);
-
- if (chars == 0) {
-#ifdef _DEBUG
- fprintf(stderr, "Unicode translation error %d\n", GetLastError());
-#endif
- return 0;
- }
-
- *to = (char*)SAFE_MALLOC((chars + 1) * sizeof(char));
- if (*to == nullptr) {
-#ifdef _DEBUG
- fprintf(stderr, "Out of memory processing string to local charset\n");
-#endif
- return 0;
- }
-
- int err = WideCharToMultiByte(wCp, WC_COMPOSITECHECK, unicode, -1, *to, (int)chars, nullptr, nullptr);
- if (err != (int)chars) {
-#ifdef _DEBUG
- fprintf(stderr, "Unicode translation error %d\n", GetLastError());
-#endif
- SAFE_FREE(to);
- return 0;
- }
-
- nResult = 1;
- }
-
- return nResult;
-}
-
-
-// Standard version with current codepage
-int __stdcall utf8_decode(const char *from, char **to)
-{
- return utf8_decode_codepage(from, to, CP_ACP);
-}
-
-
-// Returns 0 on error, 1 on success
-int __stdcall utf8_decode_static(const char *from, char *to, size_t to_size)
-{
- int nResult = 0;
-
- _ASSERTE(to); // You passed a zero pointer
-
- // Validate the string
- if (!UTF8_IsValid(from))
- return 0;
-
- // Clear target
- memset(to, 0, to_size);
-
- // Use the native conversion routines when available
- if (bHasCP_UTF8) {
- size_t inlen = mir_strlen(from) + 1;
- WCHAR *wszTemp = (WCHAR*)_alloca(inlen * sizeof(WCHAR));
- memset(wszTemp, 0, (inlen * sizeof(WCHAR)));
-
- // Convert the UTF-8 string to UCS
- if (MultiByteToWideChar(CP_UTF8, 0, from, -1, wszTemp, (int)inlen)) {
- // Convert the UCS string to local ANSI codepage
- if (WideCharToMultiByte(CP_ACP, 0, wszTemp, -1, to, (int)to_size, nullptr, nullptr)) {
- nResult = 1;
- }
- }
- }
- else {
- size_t chars = mir_strlen(from) + 1;
- WCHAR *unicode = (WCHAR*)_alloca(chars * sizeof(WCHAR));
-
- make_unicode_string_static(from, unicode, chars);
-
- WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, to, (int)to_size, nullptr, nullptr);
-
- nResult = 1;
- }
-
- return nResult;
-}
-
-
-WCHAR* __stdcall ansi_to_unicode(const char *ansi)
-{
- int wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansi, (int)mir_strlen(ansi), nullptr, 0);
-
- if (wchars == 0) {
-#ifdef _DEBUG
- fprintf(stderr, "Unicode translation error %d\n", GetLastError());
-#endif
- return nullptr;
- }
-
- WCHAR *unicode = (WCHAR*)SAFE_MALLOC((wchars + 1) * sizeof(WCHAR));
-
- int err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansi, (int)mir_strlen(ansi), unicode, wchars);
- if (err != wchars) {
-#ifdef _DEBUG
- fprintf(stderr, "Unicode translation error %d\n", GetLastError());
-#endif
- SAFE_FREE(&unicode);
- return nullptr;
- }
- return unicode;
-}
-
-
-char* __stdcall unicode_to_ansi_static(const WCHAR *unicode, char *ansi, size_t ansi_size)
-{
- memset(ansi, 0, ansi_size);
-
- if (WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, (int)mir_wstrlen(unicode), ansi, (int)ansi_size, nullptr, nullptr) > 1)
- return ansi;
-
- return nullptr;
-}
-
-char* __stdcall unicode_to_ansi(const WCHAR *unicode)
-{
- int chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, (int)mir_wstrlen(unicode), nullptr, 0, nullptr, nullptr);
-
- if (chars == 0) {
-#ifdef _DEBUG
- fprintf(stderr, "Unicode translation error %d\n", GetLastError());
-#endif
- return nullptr;
- }
-
- char* ansi = (char*)SAFE_MALLOC((chars + 1) * sizeof(char));
- if (ansi == nullptr) {
-#ifdef _DEBUG
- fprintf(stderr, "Out of memory processing string to local charset\n");
-#endif
- return nullptr;
- }
-
- int err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, (int)mir_wstrlen(unicode), ansi, chars, nullptr, nullptr);
- if (err != chars) {
-#ifdef _DEBUG
- fprintf(stderr, "Unicode translation error %d\n", GetLastError());
-#endif
- return nullptr;
- }
-
- return ansi;
-}
diff --git a/protocols/IcqOscarJ/src/i18n.h b/protocols/IcqOscarJ/src/i18n.h
deleted file mode 100644
index 5e1ebb1156..0000000000
--- a/protocols/IcqOscarJ/src/i18n.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Helper functions to convert text messages between different character sets.
-// -----------------------------------------------------------------------------
-
-#ifndef __I18N_H
-#define __I18N_H
-
-BOOL CALLBACK IsUSASCII(const char *pBuffer, size_t nSize);
-BOOL CALLBACK IsUnicodeAscii(const WCHAR *pBuffer, size_t nSize);
-int CALLBACK UTF8_IsValid(const char *pszInput);
-
-int CALLBACK get_utf8_size(const WCHAR *unicode);
-
-char* CALLBACK detect_decode_utf8(const char *from);
-
-WCHAR* CALLBACK make_unicode_string(const char *utf8);
-WCHAR* CALLBACK make_unicode_string_static(const char *utf8, WCHAR *unicode, size_t unicode_size);
-
-char* CALLBACK make_utf8_string(const WCHAR *unicode);
-char* CALLBACK make_utf8_string_static(const WCHAR *unicode, char *utf8, size_t utf_size);
-
-char* CALLBACK ansi_to_utf8(const char *ansi);
-char* CALLBACK ansi_to_utf8_codepage(const char *ansi, WORD wCp);
-
-WCHAR* CALLBACK ansi_to_unicode(const char *ansi);
-char* CALLBACK unicode_to_ansi(const WCHAR *unicode);
-char* CALLBACK unicode_to_ansi_static(const WCHAR *unicode, char *ansi, size_t ansi_size);
-
-int CALLBACK utf8_encode(const char *from, char **to);
-int CALLBACK utf8_decode(const char *from, char **to);
-int CALLBACK utf8_decode_codepage(const char *from, char **to, WORD wCp);
-int CALLBACK utf8_decode_static(const char *from, char *to, size_t to_size);
-
-void InitI18N(void);
-
-#endif /* __I18N_H */
diff --git a/protocols/IcqOscarJ/src/icq_advsearch.cpp b/protocols/IcqOscarJ/src/icq_advsearch.cpp
deleted file mode 100644
index 552efc5798..0000000000
--- a/protocols/IcqOscarJ/src/icq_advsearch.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-static void InitComboBox(HWND hwndCombo, const FieldNamesItem *names)
-{
- SendMessage(hwndCombo, CB_SETCURSEL, ComboBoxAddStringUtf(hwndCombo, nullptr, 0), 0);
-
- if (names) {
- for (int i = 0; names[i].text; i++)
- ComboBoxAddStringUtf(hwndCombo, names[i].text, names[i].code);
- }
- else {
- int ctryCount;
- struct CountryListEntry *countries;
- CallService(MS_UTILS_GETCOUNTRYLIST, (WPARAM)&ctryCount, (LPARAM)&countries);
- for (int i = 0; i < ctryCount; i++)
- if (countries[i].id != 0xFFFF && countries[i].id != 0)
- ComboBoxAddStringUtf(hwndCombo, LPGEN(countries[i].szName), countries[i].id);
- }
-}
-
-INT_PTR CALLBACK AdvancedSearchDlgProc(HWND hwndDlg, UINT message, WPARAM, LPARAM)
-{
- switch (message) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- InitComboBox(GetDlgItem(hwndDlg, IDC_GENDER), genderField);
- InitComboBox(GetDlgItem(hwndDlg, IDC_AGERANGE), agesField);
- InitComboBox(GetDlgItem(hwndDlg, IDC_MARITALSTATUS), maritalField);
- InitComboBox(GetDlgItem(hwndDlg, IDC_WORKFIELD), occupationField);
- InitComboBox(GetDlgItem(hwndDlg, IDC_ORGANISATION), affiliationField);
- InitComboBox(GetDlgItem(hwndDlg, IDC_LANGUAGE), languageField);
- InitComboBox(GetDlgItem(hwndDlg, IDC_COUNTRY), countryField);
- InitComboBox(GetDlgItem(hwndDlg, IDC_INTERESTSCAT), interestsField);
- InitComboBox(GetDlgItem(hwndDlg, IDC_PASTCAT), pastField);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static DWORD getCurItemData(HWND hwndDlg, UINT iCtrl)
-{
- return SendDlgItemMessage(hwndDlg, iCtrl, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, iCtrl, CB_GETCURSEL, 0, 0), 0);
-}
-
-static void searchPackTLVLNTS(PBYTE *buf, size_t *buflen, HWND hwndDlg, UINT idControl, WORD wType)
-{
- char str[512];
-
- GetDlgItemTextA(hwndDlg, idControl, str, _countof(str));
-
- ppackLETLVLNTS(buf, buflen, str, wType, 0);
-}
-
-static void searchPackTLVWordLNTS(PBYTE *buf, size_t *buflen, HWND hwndDlg, UINT idControl, WORD w, WORD wType)
-{
- char str[512];
-
- GetDlgItemTextA(hwndDlg, idControl, str, _countof(str));
-
- ppackLETLVWordLNTS(buf, buflen, w, str, wType, 0);
-}
-
-static PBYTE createAdvancedSearchStructureTLV(HWND hwndDlg, size_t *length)
-{
- PBYTE buf = nullptr;
- size_t buflen = 0;
-
- ppackLEWord(&buf, &buflen, META_SEARCH_GENERIC); /* subtype: full search */
-
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_FIRSTNAME, TLV_FIRSTNAME);
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_LASTNAME, TLV_LASTNAME);
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_NICK, TLV_NICKNAME);
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_EMAIL, TLV_EMAIL);
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_CITY, TLV_CITY);
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_STATE, TLV_STATE);
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_COMPANY, TLV_COMPANY);
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_DEPARTMENT, TLV_DEPARTMENT);
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_POSITION, TLV_POSITION);
- searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_KEYWORDS, TLV_KEYWORDS);
-
- ppackLETLVDWord(&buf, &buflen, (DWORD)getCurItemData(hwndDlg, IDC_AGERANGE), TLV_AGERANGE, 0);
-
- BYTE b = (BYTE)getCurItemData(hwndDlg, IDC_GENDER);
- switch (b) {
- case 'F': b = 1; break;
- case 'M': b = 2; break;
- default: b = 0;
- }
- ppackLETLVByte(&buf, &buflen, b, TLV_GENDER, 0);
- ppackLETLVByte(&buf, &buflen, (BYTE)getCurItemData(hwndDlg, IDC_MARITALSTATUS), TLV_MARITAL, 0);
- ppackLETLVWord(&buf, &buflen, (WORD)getCurItemData(hwndDlg, IDC_LANGUAGE), TLV_LANGUAGE, 0);
- ppackLETLVWord(&buf, &buflen, (WORD)getCurItemData(hwndDlg, IDC_COUNTRY), TLV_COUNTRY, 0);
- ppackLETLVWord(&buf, &buflen, (WORD)getCurItemData(hwndDlg, IDC_WORKFIELD), TLV_OCUPATION, 0);
-
- WORD w = (WORD)getCurItemData(hwndDlg, IDC_PASTCAT);
- searchPackTLVWordLNTS(&buf, &buflen, hwndDlg, IDC_PASTKEY, w, TLV_PASTINFO);
-
- w = (WORD)getCurItemData(hwndDlg, IDC_INTERESTSCAT);
- searchPackTLVWordLNTS(&buf, &buflen, hwndDlg, IDC_INTERESTSKEY, w, TLV_INTERESTS);
-
- w = (WORD)getCurItemData(hwndDlg, IDC_ORGANISATION);
- searchPackTLVWordLNTS(&buf, &buflen, hwndDlg, IDC_ORGKEYWORDS, w, TLV_AFFILATIONS);
-
- w = (WORD)getCurItemData(hwndDlg, IDC_HOMEPAGECAT);
- if (w != 0xFFFF)
- searchPackTLVWordLNTS(&buf, &buflen, hwndDlg, IDC_HOMEPAGEKEY, w, TLV_HOMEPAGE);
-
- if (IsDlgButtonChecked(hwndDlg, IDC_ONLINEONLY))
- ppackLETLVByte(&buf, &buflen, 1, TLV_ONLINEONLY, 1);
-
- if (length)
- *length = buflen;
-
- return buf;
-}
-
-PBYTE createAdvancedSearchStructure(HWND hwndDlg, size_t *length)
-{
- if (!hwndDlg)
- return nullptr;
-
- return createAdvancedSearchStructureTLV(hwndDlg, length);
-}
diff --git a/protocols/IcqOscarJ/src/icq_advsearch.h b/protocols/IcqOscarJ/src/icq_advsearch.h
deleted file mode 100644
index d04e8b8e31..0000000000
--- a/protocols/IcqOscarJ/src/icq_advsearch.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001,2002 Jon Keating, Richard Hughes
-// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#pragma once
-
-INT_PTR CALLBACK AdvancedSearchDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
-PBYTE createAdvancedSearchStructure(HWND hwndDlg, size_t *length);
diff --git a/protocols/IcqOscarJ/src/icq_avatar.cpp b/protocols/IcqOscarJ/src/icq_avatar.cpp
deleted file mode 100644
index eb747258d0..0000000000
--- a/protocols/IcqOscarJ/src/icq_avatar.cpp
+++ /dev/null
@@ -1,1315 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Manages Avatar connection, provides internal service for handling avatars
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-#include "m_folders.h"
-
-BYTE hashEmptyAvatar[9] = { 0x00, 0x01, 0x00, 0x05, 0x02, 0x01, 0xD2, 0x04, 0x72 };
-
-avatars_request::avatars_request(int type)
-{
- this->type = type;
-}
-
-avatars_request::~avatars_request()
-{
- if (this) {
- switch (type) {
- case ART_UPLOAD:
- SAFE_FREE((void**)&pData);
- break;
- case ART_GET:
- SAFE_FREE((void**)&hash);
- SAFE_FREE(&szFile);
- break;
- case ART_BLOCK:
- break;
- }
- }
-}
-
-wchar_t* CIcqProto::GetOwnAvatarFileName()
-{
- DBVARIANT dbvFile = { DBVT_DELETED };
- if (getWString(NULL, "AvatarFile", &dbvFile))
- return nullptr;
-
- wchar_t tmp[MAX_PATH * 2];
- PathToAbsoluteW(dbvFile.pwszVal, tmp);
- db_free(&dbvFile);
-
- return null_strdup(tmp);
-}
-
-void CIcqProto::GetFullAvatarFileName(int dwUin, const char *szUid, int dwFormat, wchar_t *pszDest, size_t cbLen)
-{
- GetAvatarFileName(dwUin, szUid, pszDest, cbLen);
- AddAvatarExt(dwFormat, pszDest);
-}
-
-void CIcqProto::GetAvatarFileName(int dwUin, const char *szUid, wchar_t *pszDest, size_t cbLen)
-{
- wchar_t szPath[MAX_PATH * 2];
- mir_snwprintf(szPath, L"%s\\%S\\", VARSW(L"%miranda_avatarcache%"), m_szModuleName);
-
- FOLDERSGETDATA fgd = { sizeof(fgd) };
- fgd.nMaxPathSize = _countof(szPath);
- fgd.szPathT = szPath;
- fgd.flags = FF_TCHAR;
-
- // fill the destination
- mir_wstrncpy(pszDest, szPath, cbLen - 1);
- size_t tPathLen = mir_wstrlen(pszDest);
-
- // make sure the avatar cache directory exists
- CreateDirectoryTreeW(szPath);
-
- if (dwUin != 0)
- _ltow(dwUin, pszDest + tPathLen, 10);
- else if (szUid) {
- wchar_t* p = mir_a2u(szUid);
- mir_wstrcpy(pszDest + tPathLen, p);
- mir_free(p);
- }
- else {
- wchar_t szBuf[MAX_PATH];
- if (Profile_GetNameW(MAX_PATH, szBuf))
- mir_wstrcpy(pszDest + tPathLen, L"avatar");
- else {
- wchar_t *szLastDot = wcsrchr(szBuf, '.');
- if (szLastDot)
- szLastDot[0] = '\0';
-
- mir_wstrcpy(pszDest + tPathLen, szBuf);
- mir_wstrcat(pszDest + tPathLen, L"_avt");
- }
- }
-}
-
-void AddAvatarExt(int dwFormat, wchar_t *pszDest)
-{
- const wchar_t *ext = ProtoGetAvatarExtension(dwFormat);
- mir_wstrcat(pszDest, (*ext == 0) ? L".dat" : ext);
-}
-
-#define MD5_BLOCK_SIZE 1024*1024 /* use 1MB blocks */
-
-BYTE* calcMD5HashOfFile(const wchar_t *tszFile)
-{
- BYTE *res = nullptr;
-
- HANDLE hFile = nullptr, hMap = nullptr;
- if ((hFile = CreateFile(tszFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr)) != INVALID_HANDLE_VALUE) {
- if ((hMap = CreateFileMapping(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr)) != nullptr) {
- long cbFileSize = GetFileSize(hFile, nullptr);
-
- res = (BYTE*)SAFE_MALLOC(16 * sizeof(BYTE));
- if (cbFileSize != 0 && res) {
- mir_md5_state_t state;
- BYTE digest[16];
- int dwOffset = 0;
-
- mir_md5_init(&state);
- while (dwOffset < cbFileSize) {
- BYTE *ppMap = nullptr;
- int dwBlockSize = min(MD5_BLOCK_SIZE, cbFileSize - dwOffset);
- if (!(ppMap = (BYTE*)MapViewOfFile(hMap, FILE_MAP_READ, 0, dwOffset, dwBlockSize)))
- break;
-
- mir_md5_append(&state, (const BYTE *)ppMap, dwBlockSize);
- UnmapViewOfFile(ppMap);
- dwOffset += dwBlockSize;
- }
- mir_md5_finish(&state, digest);
- memcpy(res, digest, 16 * sizeof(BYTE));
- }
- }
-
- if (hMap != nullptr) CloseHandle(hMap);
- if (hFile != nullptr) CloseHandle(hFile);
- }
-
- return res;
-}
-
-int CIcqProto::IsAvatarChanged(MCONTACT hContact, const BYTE *pHash, size_t nHashLen)
-{
- DBVARIANT dbvSaved = { 0 };
- if (getSetting(hContact, "AvatarSaved", &dbvSaved))
- return 1; // saved Avatar hash is missing
-
- // are the hashes different?
- int ret = (dbvSaved.cpbVal != nHashLen || memcmp(dbvSaved.pbVal, pHash, nHashLen)) ? 2 : 0;
- db_free(&dbvSaved);
- return ret;
-}
-
-void CIcqProto::StartAvatarThread(HNETLIBCONN hConn, char *cookie, size_t cookieLen) // called from event
-{
- if (!hConn) {
- mir_cslock l(m_avatarsMutex); // place avatars lock
-
- if (m_avatarsConnection && m_avatarsConnection->isPending()) {
- debugLogA("Avatar, Multiple start thread attempt, ignored.");
- SAFE_FREE((void**)&cookie);
- return;
- }
- debugLogA("Avatars: Connection failed");
-
- m_avatarsConnectionPending = FALSE;
-
- // check if any upload request are waiting in the queue
- int bYet = 0;
-
- auto T = m_arAvatars.rev_iter();
- for (auto &it : T) {
- if (it->type == ART_UPLOAD) { // we found it, return error
- if (!bYet) {
- icq_LogMessage(LOG_WARNING, LPGEN("Error uploading avatar to server, server temporarily unavailable."));
- bYet = 1;
- }
-
- // remove upload request from queue
- delete it;
- m_arAvatars.remove(T.indexOf(&it));
- }
- }
-
- SAFE_FREE((void**)&cookie);
- return;
- }
-
- mir_cslock l(m_avatarsMutex);
-
- if (m_avatarsConnection && m_avatarsConnection->isPending()) {
- debugLogA("Avatar, Multiple start thread attempt, ignored.");
-
- NetLib_CloseConnection(&hConn, false);
-
- SAFE_FREE((void**)&cookie);
- return;
- }
-
- if (m_avatarsConnection)
- m_avatarsConnection->closeConnection();
- m_avatarsConnection = new avatars_server_connection(this, hConn, cookie, cookieLen); // the old connection should not be used anymore
-
- // connection object created, remove the connection request pending flag
- m_avatarsConnectionPending = false;
-}
-
-void CIcqProto::StopAvatarThread()
-{
- mir_cslock l(m_avatarsMutex); // the connection is about to close
- if (m_avatarsConnection)
- m_avatarsConnection->shutdownConnection(); // make the thread stop
-}
-
-// handle Owner's avatar hash changes
-void CIcqProto::handleAvatarOwnerHash(BYTE bFlags, BYTE *pData, size_t nDataLen)
-{
- if (nDataLen < 0x14 || !m_bAvatarsEnabled)
- return;
-
- switch (bFlags) {
- case 1: // our avatar is on the server
- setSettingBlob(NULL, "AvatarHash", pData, 0x14); /// TODO: properly handle multiple avatar items (more formats)
- setUserInfo();
- {
- // here we need to find a file, check its hash, if invalid get avatar from server
- wchar_t *file = GetOwnAvatarFileName();
- if (!file) { // we have no avatar file, download from server
- debugLogA("We have no avatar, requesting from server.");
-
- wchar_t szFile[MAX_PATH * 2 + 4];
- GetAvatarFileName(0, nullptr, szFile, MAX_PATH * 2);
- GetAvatarData(NULL, m_dwLocalUIN, nullptr, pData, 0x14, szFile);
- }
- else { // we know avatar filename
- BYTE *hash = calcMD5HashOfFile(file);
-
- if (!hash) { // hash could not be calculated - probably missing file, get avatar from server
- debugLogA("We have no avatar, requesting from server.");
-
- wchar_t szFile[MAX_PATH * 2 + 4];
- GetAvatarFileName(0, nullptr, szFile, MAX_PATH * 2);
- GetAvatarData(NULL, m_dwLocalUIN, nullptr, pData, 0x14, szFile);
- }
- // check if we had set any avatar if yes set our, if not download from server
- else if (memcmp(hash, pData + 4, 0x10)) { // we have different avatar, sync that
- if (m_bSsiEnabled && getByte("ForceOurAvatar", 1)) { // we want our avatar, update hash
- DWORD dwPaFormat = ::ProtoGetAvatarFileFormat(file);
- BYTE pHash[0x14];
-
- debugLogA("Our avatar is different, setting our new hash.");
-
- pHash[0] = 0;
- pHash[1] = dwPaFormat == PA_FORMAT_XML ? AVATAR_HASH_FLASH : AVATAR_HASH_STATIC;
- pHash[2] = 1; // state of the hash
- pHash[3] = 0x10; // len of the hash
- memcpy((pHash + 4), hash, 0x10);
- updateServAvatarHash(pHash, 0x14);
- }
- else { // get avatar from server
- debugLogA("We have different avatar, requesting new from server.");
-
- wchar_t tszFile[MAX_PATH * 2 + 4];
- GetAvatarFileName(0, nullptr, tszFile, MAX_PATH * 2);
- GetAvatarData(NULL, m_dwLocalUIN, nullptr, pData, 0x14, tszFile);
- }
- }
- SAFE_FREE((void**)&hash);
- SAFE_FREE(&file);
- }
- }
- break;
-
- case 0x41: // request to upload avatar data
- case 0x81:
- // request to re-upload avatar data
- if (m_bSsiEnabled) { // we could not change serv-list if it is disabled...
- wchar_t *file = GetOwnAvatarFileName();
- if (!file) { // we have no file to upload, remove hash from server
- debugLogA("We do not have avatar, removing hash.");
- SetMyAvatar(0, 0);
- break;
- }
-
- DWORD dwPaFormat = ::ProtoGetAvatarFileFormat(file);
- BYTE *hash = calcMD5HashOfFile(file);
- if (!hash) { // the hash could not be calculated, remove from server
- debugLogA("We could not obtain hash, removing hash.");
- SetMyAvatar(0, 0);
- }
- else if (!memcmp(hash, pData + 4, 0x10)) { // we have the right file
- HANDLE hFile = nullptr, hMap = nullptr;
- BYTE *ppMap = nullptr;
- long cbFileSize = 0;
-
- debugLogA("Uploading our avatar data.");
-
- if ((hFile = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr)) != INVALID_HANDLE_VALUE)
- if ((hMap = CreateFileMapping(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr)) != nullptr)
- if ((ppMap = (BYTE*)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != nullptr)
- cbFileSize = GetFileSize(hFile, nullptr);
-
- if (cbFileSize != 0)
- SetAvatarData(NULL, (WORD)(dwPaFormat == PA_FORMAT_XML ? AVATAR_HASH_FLASH : AVATAR_HASH_STATIC), ppMap, cbFileSize);
-
- if (ppMap != nullptr) UnmapViewOfFile(ppMap);
- if (hMap != nullptr) CloseHandle(hMap);
- if (hFile != nullptr) CloseHandle(hFile);
- SAFE_FREE((void**)&hash);
- }
- else {
- BYTE pHash[0x14];
-
- debugLogA("Our file is different, set our new hash.");
-
- pHash[0] = 0;
- pHash[1] = dwPaFormat == PA_FORMAT_XML ? AVATAR_HASH_FLASH : AVATAR_HASH_STATIC;
- pHash[2] = 1; // state of the hash
- pHash[3] = 0x10; // len of the hash
- memcpy((pHash + 4), hash, 0x10);
- updateServAvatarHash(pHash, 0x14);
-
- SAFE_FREE((void**)&hash);
- }
-
- SAFE_FREE(&file);
- }
- break;
-
- default:
- debugLogA("Received UNKNOWN Avatar Status.");
- }
-}
-
-// handle Contact's avatar hash
-void CIcqProto::handleAvatarContactHash(DWORD dwUIN, char *szUID, MCONTACT hContact, BYTE *pHash, size_t nHashLen)
-{
- int bJob = FALSE;
- BOOL avatarInfoPresent = FALSE;
- int avatarType = -1;
- BYTE *pAvatarHash = nullptr;
- size_t cbAvatarHash = 0;
- BYTE emptyItem[0x10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- if (!m_bAvatarsEnabled || nHashLen < 4)
- return; // only if enabled
-
- while (nHashLen >= 4) { // parse online message items one by one
- WORD itemType = pHash[0] << 8 | pHash[1];
- size_t itemLen = pHash[3];
-
- // just some validity check
- if (itemLen + 4 > nHashLen)
- itemLen = nHashLen - 4;
-
- if (itemLen && memcmp(pHash + 4, emptyItem, itemLen > 0x10 ? 0x10 : itemLen)) {
- // Item types
- // 0000: AIM mini avatar
- // 0001: AIM/ICQ avatar ID/hash (len 5 or 16 bytes)
- // 0002: iChat online message
- // 0008: ICQ Flash avatar hash (16 bytes)
- // 0009: iTunes music store link
- // 000C: ICQ contact photo (16 bytes)
- // 000D: Last update time of online message
- // 000E: Status mood
- if (itemType == AVATAR_HASH_MINI && itemLen == 0x05 && avatarType == -1) { // mini avatar
- pAvatarHash = pHash;
- cbAvatarHash = itemLen + 4;
- avatarType = itemType;
- }
- else if (itemType == AVATAR_HASH_STATIC && (itemLen == 0x05 || itemLen == 0x10) && (avatarType == -1 || avatarType == AVATAR_HASH_MINI)) { // normal avatar
- pAvatarHash = pHash;
- cbAvatarHash = itemLen + 4;
- avatarType = itemType;
- }
- else if (itemType == AVATAR_HASH_FLASH && itemLen == 0x10 && (avatarType == -1 || avatarType == AVATAR_HASH_MINI || avatarType == AVATAR_HASH_STATIC)) { // flash avatar
- pAvatarHash = pHash;
- cbAvatarHash = itemLen + 4;
- avatarType = itemType;
- }
- else if (itemType == AVATAR_HASH_PHOTO && itemLen == 0x10) { // big avatar (ICQ 6+)
- pAvatarHash = pHash;
- cbAvatarHash = itemLen + 4;
- avatarType = itemType;
- }
- }
- else if ((itemLen == 0) && (itemType == AVATAR_HASH_MINI || itemType == AVATAR_HASH_STATIC || itemType == AVATAR_HASH_FLASH || itemType == AVATAR_HASH_PHOTO))
- // empty item - indicating that avatar of that type was removed
- avatarInfoPresent = TRUE;
-
- pHash += itemLen + 4;
- nHashLen -= itemLen + 4;
- }
-
- if (avatarType != -1) { // check settings, should we request avatar immediatelly?
- DBVARIANT dbv = { DBVT_DELETED };
- wchar_t tszAvatar[MAX_PATH * 2 + 4];
- BYTE bAutoLoad = getByte("AvatarsAutoLoad", DEFAULT_LOAD_AVATARS);
-
- if ((avatarType == AVATAR_HASH_STATIC || avatarType == AVATAR_HASH_MINI) && cbAvatarHash == 0x09 && !memcmp(pAvatarHash + 4, hashEmptyAvatar + 4, 0x05)) { // empty avatar - unlink image, clear hash
- if (!getSetting(hContact, "AvatarHash", &dbv)) { // contact had avatar, clear hash, notify UI
- db_free(&dbv);
- debugLogA("%s has removed Avatar.", strUID(dwUIN, szUID));
-
- delSetting(hContact, "AvatarHash");
- ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr, 0);
- }
- else debugLogA("%s has empty Avatar.", strUID(dwUIN, szUID));
- return;
- }
-
- if (getSetting(hContact, "AvatarHash", &dbv)) { // we did not find old avatar hash, i.e. get new avatar
- int avatarState = IsAvatarChanged(hContact, pAvatarHash, cbAvatarHash);
-
- // check saved hash and file, if equal only store hash
- if (!avatarState) { // hashes are the same
- int dwPaFormat = getByte(hContact, "AvatarType", PA_FORMAT_UNKNOWN);
-
- GetFullAvatarFileName(dwUIN, szUID, dwPaFormat, tszAvatar, MAX_PATH * 2);
- if (_waccess(tszAvatar, 0) == 0) { // the file is there, link to contactphoto, save hash
- debugLogA("%s has published Avatar. Image was found in the cache.", strUID(dwUIN, szUID));
-
- setSettingBlob(hContact, "AvatarHash", pAvatarHash, cbAvatarHash);
- ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr, 0);
- }
- else { // the file was lost, request avatar again
- debugLogA("%s has published Avatar.", strUID(dwUIN, szUID));
- bJob = TRUE;
- }
- }
- else { // the hash is not the one we want, request avatar
- debugLogA("%s has published a new Avatar.", strUID(dwUIN, szUID));
- bJob = TRUE;
- }
- }
- else { // we found hash check if it changed or not
- if ((dbv.cpbVal != cbAvatarHash) || memcmp(dbv.pbVal, pAvatarHash, cbAvatarHash)) { // the hash is different, request new avatar
- debugLogA("%s has changed Avatar.", strUID(dwUIN, szUID));
- bJob = TRUE;
- }
- else { // the hash was not changed, check if we have the correct file
- int avatarState = IsAvatarChanged(hContact, pAvatarHash, cbAvatarHash);
-
- // we should have file, check if the file really exists
- if (!avatarState) {
- int dwPaFormat = getByte(hContact, "AvatarType", PA_FORMAT_UNKNOWN);
- if (dwPaFormat == PA_FORMAT_UNKNOWN) { // we do not know the format, get avatar again
- debugLogA("%s has Avatar. Image is missing.", strUID(dwUIN, szUID));
- bJob = 2;
- }
- else {
- GetFullAvatarFileName(dwUIN, szUID, dwPaFormat, tszAvatar, MAX_PATH * 2);
- if (_waccess(tszAvatar, 0) != 0) { // the file was lost, get it again
- debugLogA("%s has Avatar. Image is missing.", strUID(dwUIN, szUID));
- bJob = 2;
- }
- else debugLogA("%s has Avatar. Image was found in the cache.", strUID(dwUIN, szUID));
- }
- }
- else { // the hash is not the one we want, request avatar
- debugLogA("%s has Avatar. Image was not retrieved yet.", strUID(dwUIN, szUID));
- bJob = 2;
- }
- }
- db_free(&dbv);
- }
-
- if (bJob) {
- if (bJob == TRUE) { // Remove possible block - hash changed, try again.
- mir_cslock l(m_avatarsMutex);
-
- for (auto &it : m_arAvatars) {
- if (it->hContact == hContact && it->type == ART_BLOCK) { // found one, remove
- delete it;
- m_arAvatars.removeItem(&it);
- break;
- }
- }
- }
-
- setSettingBlob(hContact, "AvatarHash", pAvatarHash, cbAvatarHash);
-
- ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr, 0);
-
- if (bAutoLoad) { // auto-load is on, so request the avatar now, otherwise we are done
- GetAvatarFileName(dwUIN, szUID, tszAvatar, MAX_PATH * 2);
- GetAvatarData(hContact, dwUIN, szUID, pAvatarHash, cbAvatarHash, tszAvatar);
- } // avatar request sent or added to queue
- }
- }
- else if (avatarInfoPresent) { // hash was not found, clear the hash
- DBVARIANT dbv = { DBVT_DELETED };
- if (!getSetting(hContact, "AvatarHash", &dbv)) { // contact had avatar, clear hash, notify UI
- db_free(&dbv);
- debugLogA("%s has removed Avatar.", strUID(dwUIN, szUID));
-
- delSetting(hContact, "AvatarHash");
- ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr, 0);
- }
- else debugLogA("%s has no Avatar.", strUID(dwUIN, szUID));
- }
-}
-
-// request avatar data from server
-int CIcqProto::GetAvatarData(MCONTACT hContact, DWORD dwUin, const char *szUid, const BYTE *hash, size_t hashlen, const wchar_t *file)
-{
- uid_str szUidData;
- char *pszUid = nullptr;
- if (!dwUin && szUid) { // create a copy in local writable buffer
- mir_strcpy(szUidData, szUid);
- pszUid = szUidData;
- }
-
- mir_cslockfull alck(m_avatarsMutex);
-
- if (m_avatarsConnection && m_avatarsConnection->isReady()) { // check if we are ready
- // check if requests for this user are not blocked
- auto T = m_arAvatars.rev_iter();
- for (auto &ar : T) {
- if (ar->hContact == hContact && ar->type == ART_BLOCK) { // found a block item
- if (GetTickCount() > ar->timeOut) { // remove timeouted block
- delete ar;
- m_arAvatars.remove(T.indexOf(&ar));
- continue;
- }
- debugLogA("Avatars: Requests for %s avatar are blocked.", strUID(dwUin, pszUid));
- return 0;
- }
- }
-
- mir_cslock l(m_avatarsConnection->getLock());
- alck.unlock();
-
- DWORD dwCookie = m_avatarsConnection->sendGetAvatarRequest(hContact, dwUin, pszUid, hash, hashlen, file);
- if (dwCookie) // return now if the request was sent successfully
- return dwCookie;
-
- alck.lock();
- }
- // we failed to send request, or avatar thread not ready
-
- // check if any request for this user is not already in the queue
- auto T = m_arAvatars.rev_iter();
- for (auto &ar : T) {
- if (ar->hContact == hContact) { // we found it, return error
- if (ar->type == ART_BLOCK && GetTickCount() > ar->timeOut) { // remove timeouted block
- delete ar;
- m_arAvatars.remove(T.indexOf(&ar));
- continue;
- }
- alck.unlock();
- debugLogA("Avatars: Ignoring duplicate get %s avatar request.", strUID(dwUin, pszUid));
-
- // make sure avatar connection is in progress
- requestAvatarConnection();
- return 0;
- }
- }
-
- // add request to queue, processed after successful login
- avatars_request *ar = new avatars_request(ART_GET); // get avatar
- ar->hContact = hContact;
- ar->dwUin = dwUin;
- if (!dwUin)
- mir_strcpy(ar->szUid, szUid);
- ar->hash = (BYTE*)SAFE_MALLOC(hashlen);
- if (!ar->hash) { // alloc failed
- delete ar;
- return 0;
- }
- memcpy(ar->hash, hash, hashlen); // copy the data
- ar->hashlen = hashlen;
- ar->szFile = null_strdup(file); // duplicate the string
- m_arAvatars.insert(ar);
- alck.unlock();
-
- debugLogA("Avatars: Request to get %s image added to queue.", strUID(dwUin, pszUid));
-
- // make sure avatar connection is in progress
- requestAvatarConnection();
- return -1; // we added to queue
-}
-
-// upload avatar data to server
-int CIcqProto::SetAvatarData(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen)
-{
- mir_cslockfull alck(m_avatarsMutex);
-
- if (m_avatarsConnection && m_avatarsConnection->isReady()) { // check if we are ready
- mir_cslock l(m_avatarsConnection->getLock());
- alck.unlock();
-
- DWORD dwCookie = m_avatarsConnection->sendUploadAvatarRequest(hContact, wRef, data, datalen);
- if (dwCookie) // return now if the request was sent successfully
- return dwCookie;
-
- alck.lock();
- }
- // we failed to send request, or avatar thread not ready
-
- // check if any request for this user is not already in the queue
- for (auto ar : m_arAvatars) {
- if (ar->hContact == hContact && ar->type == ART_UPLOAD) { // we found it, return error
- alck.unlock();
- debugLogA("Avatars: Ignoring duplicate upload avatar request.");
-
- // make sure avatar connection is in progress
- requestAvatarConnection();
- return 0;
- }
- }
-
- // add request to queue, processed after successful login
- avatars_request *ar = new avatars_request(ART_UPLOAD); // upload avatar
- ar->hContact = hContact;
- ar->pData = (BYTE*)SAFE_MALLOC(datalen);
- if (!ar->pData) { // alloc failed
- delete ar;
- return 0;
- }
-
- memcpy(ar->pData, data, datalen); // copy the data
- ar->cbData = datalen;
- ar->wRef = wRef;
- m_arAvatars.insert(ar);
- alck.unlock();
-
- debugLogA("Avatars: Request to upload image added to queue.");
-
- // make sure avatar connection is in progress
- requestAvatarConnection();
- return -1; // we added to queue
-}
-
-void CIcqProto::requestAvatarConnection()
-{
- mir_cslockfull alck(m_avatarsMutex);
- if (!m_avatarsConnectionPending && (!m_avatarsConnection || (!m_avatarsConnection->isPending() && !m_avatarsConnection->isReady()))) {
- // avatar connection is not pending, request new one
- m_avatarsConnectionPending = TRUE;
- alck.unlock();
-
- icq_requestnewfamily(ICQ_AVATAR_FAMILY, &CIcqProto::StartAvatarThread);
- }
-}
-
-void __cdecl CIcqProto::AvatarThread(avatars_server_connection *pInfo)
-{
- debugLogA("%s thread started.", "Avatar");
- Thread_SetName("ICQ: AvatarThread");
-
- // Execute connection handler
- pInfo->connectionThread();
- {
- // Remove connection reference
- mir_cslock l(m_avatarsMutex);
- if (m_avatarsConnection == pInfo)
- m_avatarsConnection = nullptr;
-
- // Release connection handler
- delete pInfo;
- }
-
- debugLogA("%s thread ended.", "Avatar");
-}
-
-avatars_server_connection::avatars_server_connection(CIcqProto *_ppro, HNETLIBCONN _hConnection, char *_pCookie, size_t _wCookieLen) :
- isLoggedIn(false), stopThread(false), isActive(false),
- ppro(_ppro),
- pCookie(_pCookie),
- wCookieLen(_wCookieLen),
- hConnection(_hConnection)
-{
- // Initialize packet sequence
- wLocalSequence = generate_flap_sequence();
-
- // Create connection thread
- ppro->ForkThread((CIcqProto::MyThreadFunc)&CIcqProto::AvatarThread, this);
-}
-
-avatars_server_connection::~avatars_server_connection()
-{
- delete m_rates;
-}
-
-void avatars_server_connection::closeConnection()
-{
- stopThread = TRUE;
-
- mir_cslock l(localSeqMutex);
- if (hConnection) {
- Netlib_CloseHandle(hConnection);
- hConnection = nullptr;
- }
-}
-
-void avatars_server_connection::shutdownConnection()
-{
- stopThread = TRUE;
-
- mir_cslock l(localSeqMutex);
- if (hConnection)
- Netlib_Shutdown(hConnection);
-}
-
-DWORD avatars_server_connection::sendGetAvatarRequest(MCONTACT hContact, DWORD dwUin, char *szUid, const BYTE *hash, size_t hashlen, const wchar_t *file)
-{
- DWORD dwNow = GetTickCount();
-
- mir_cslockfull alck(ppro->m_avatarsMutex);
-
- for (int i = 0; i < runCount;) { // look for timeouted requests
- if (runTime[i] < dwNow) { // found outdated, remove
- runContact[i] = runContact[runCount - 1];
- runTime[i] = runTime[runCount - 1];
- runCount--;
- }
- else i++;
- }
-
- for (int i = 0; i < runCount; i++) {
- if (runContact[i] == hContact) {
- ppro->debugLogA("Ignoring duplicate get %s image request.", strUID(dwUin, szUid));
- return -1; // Success: request ignored
- }
- }
-
- if (runCount < 4) { // 4 concurent requests at most
- int bSendNow = TRUE;
- {
- // rate management
- mir_cslock l(m_ratesMutex);
- WORD wGroup = m_rates->getGroupFromSNAC(ICQ_AVATAR_FAMILY, ICQ_AVATAR_GET_REQUEST);
-
- if (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_ALERT)) { // we will be over quota if we send the request now, add to queue instead
- bSendNow = FALSE;
- ppro->debugLogA("Rates: Delay avatar request.");
- }
- }
-
- if (bSendNow) {
- runContact[runCount] = hContact;
- runTime[runCount] = GetTickCount() + 30000; // 30sec to complete request
- runCount++;
-
- alck.unlock();
-
- int nUinLen = getUIDLen(dwUin, szUid);
-
- cookie_avatar *ack = (cookie_avatar*)SAFE_MALLOC(sizeof(cookie_avatar));
- if (!ack)
- return 0; // Failure: out of memory
-
- ack->dwUin = 1; //dwUin; // I should be damned for this - only to identify get request
- ack->hContact = hContact;
- ack->hash = (BYTE*)SAFE_MALLOC(hashlen);
- memcpy(ack->hash, hash, hashlen); // copy the data
- ack->hashlen = hashlen;
- ack->szFile = null_strdup(file); // duplicate the string
-
- DWORD dwCookie = ppro->AllocateCookie(CKT_AVATAR, ICQ_AVATAR_GET_REQUEST, hContact, ack);
- icq_packet packet;
-
- serverPacketInit(&packet, 12 + nUinLen + hashlen);
- packFNACHeader(&packet, ICQ_AVATAR_FAMILY, ICQ_AVATAR_GET_REQUEST, 0, dwCookie);
- packUID(&packet, dwUin, szUid);
- packByte(&packet, 1); // unknown, probably type of request: 1 = get icon :)
- packBuffer(&packet, hash, hashlen);
-
- if (sendServerPacket(&packet)) {
- ppro->debugLogA("Request to get %s image sent.", strUID(dwUin, szUid));
- return dwCookie;
- }
- ppro->FreeCookie(dwCookie); // sending failed, free resources
- SAFE_FREE(&ack->szFile);
- SAFE_FREE((void**)&ack->hash);
- SAFE_FREE((void**)&ack);
- }
- }
-
- return 0; // Failure
-}
-
-DWORD avatars_server_connection::sendUploadAvatarRequest(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen)
-{
- cookie_avatar *ack = (cookie_avatar*)SAFE_MALLOC(sizeof(cookie_avatar));
- if (!ack)
- return 0; // Failure: out of memory
-
- ack->hContact = hContact;
-
- DWORD dwCookie = ppro->AllocateCookie(CKT_AVATAR, ICQ_AVATAR_UPLOAD_REQUEST, 0, ack);
-
- icq_packet packet;
- serverPacketInit(&packet, 14 + datalen);
- packFNACHeader(&packet, ICQ_AVATAR_FAMILY, ICQ_AVATAR_UPLOAD_REQUEST, 0, dwCookie);
- packWord(&packet, wRef); // unknown, probably reference
- packWord(&packet, (WORD)datalen);
- packBuffer(&packet, data, datalen);
-
- if (sendServerPacket(&packet)) {
- ppro->debugLogA("Upload image packet sent.");
- return dwCookie;
- }
-
- ppro->ReleaseCookie(dwCookie); // failed to send, free resources
- return 0;
-}
-
-void avatars_server_connection::checkRequestQueue()
-{
- mir_cslockfull alck(ppro->m_avatarsMutex);
-
- while (ppro->m_arAvatars.getCount() && runCount < 3) { // pick up an request and send it - happens immediatelly after login
- // do not fill queue to top, leave one place free
- avatars_request *pRequest = ppro->m_arAvatars[0];
- {
- // rate management
- mir_cslock l(m_ratesMutex);
- WORD wGroup = m_rates->getGroupFromSNAC(ICQ_AVATAR_FAMILY, (WORD)(pRequest->type == ART_UPLOAD ? ICQ_AVATAR_GET_REQUEST : ICQ_AVATAR_UPLOAD_REQUEST));
-
- // we are over rate, leave queue and wait
- if (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_ALERT))
- break;
- }
-
- if (pRequest->type == ART_BLOCK) { // block contact processing
- auto T = ppro->m_arAvatars.rev_iter();
- for (auto &ar : T) {
- if (GetTickCount() > ar->timeOut) { // expired contact block, remove
- delete ar;
- ppro->m_arAvatars.remove(T.indexOf(&ar));
- }
- }
- return; // end processing
- }
-
- ppro->m_arAvatars.remove(int(0));
- alck.unlock();
-
- switch (pRequest->type) {
- case ART_GET: // get avatar
- sendGetAvatarRequest(pRequest->hContact, pRequest->dwUin, pRequest->szUid, pRequest->hash, pRequest->hashlen, pRequest->szFile);
- break;
-
- case ART_UPLOAD: // set avatar
- sendUploadAvatarRequest(pRequest->hContact, pRequest->wRef, pRequest->pData, pRequest->cbData);
- break;
- }
- delete pRequest;
-
- alck.lock();
- }
-}
-
-void avatars_server_connection::connectionThread()
-{
- // This is the "infinite" loop that receives the packets from the ICQ avatar server
- DWORD dwLastKeepAlive = time(0) + KEEPALIVE_INTERVAL;
-
- hPacketRecver = Netlib_CreatePacketReceiver(hConnection, 65536);
-
- NETLIBPACKETRECVER packetRecv = {};
- packetRecv.dwTimeout = 1000; // timeout - for stopThread to work
- while (!stopThread) {
- int recvResult = Netlib_GetMorePackets(hPacketRecver, &packetRecv);
- if (recvResult == 0) {
- ppro->debugLogA("Clean closure of avatar socket");
- break;
- }
-
- if (recvResult == SOCKET_ERROR) {
- if (GetLastError() == ERROR_TIMEOUT) { // timeout, check if we should be still running
- if (Miranda_IsTerminated())
- break;
-
- if (time(0) >= dwLastKeepAlive) { // limit frequency (HACK: on some systems select() does not work well)
- if (!ppro->m_bGatewayMode && ppro->getByte("KeepAlive", DEFAULT_KEEPALIVE_ENABLED)) { // send keep-alive packet
- icq_packet packet;
- packet.wLen = 0;
- write_flap(&packet, ICQ_PING_CHAN);
- sendServerPacket(&packet);
- }
- dwLastKeepAlive = time(0) + KEEPALIVE_INTERVAL;
- }
-
- // check if we got something to request
- checkRequestQueue();
- continue;
- }
- if (!stopThread)
- ppro->debugLogA("Avatar socket closed abortively, error: %d", GetLastError());
- else
- ppro->debugLogA("Avatar socket gracefully closed.");
- break;
- }
-
- // Deal with the packet
- packetRecv.bytesUsed = handleServerPackets(packetRecv.buffer, packetRecv.bytesAvailable);
-
- if (isActive && (packetRecv.bytesAvailable == packetRecv.bytesUsed)) // no packets pending
- checkRequestQueue(); // process request queue
- }
- {
- // release connection
- mir_cslock l(localSeqMutex);
- NetLib_SafeCloseHandle(&hPacketRecver); // Close the packet receiver
- NetLib_CloseConnection(&hConnection, FALSE); // Close the connection
- }
- {
- // release rates
- mir_cslock l(m_ratesMutex);
- delete m_rates; m_rates = nullptr;
- }
-
- SAFE_FREE((void**)&pCookie);
-}
-
-int avatars_server_connection::sendServerPacket(icq_packet *pPacket)
-{
- int lResult = 0;
-
- // This critsec makes sure that the sequence order doesn't get screwed up
- mir_cslock l(localSeqMutex);
-
- if (hConnection) {
- // :IMPORTANT:
- // The FLAP sequence must be a WORD. When it reaches 0xFFFF it should wrap to
- // 0x0000, otherwise we'll get kicked by server.
- wLocalSequence++;
-
- // Pack sequence number
- pPacket->pData[2] = ((wLocalSequence & 0xff00) >> 8);
- pPacket->pData[3] = (wLocalSequence & 0x00ff);
-
- int nSendResult;
- for (int nRetries = 3; nRetries >= 0; nRetries--) {
- nSendResult = Netlib_Send(hConnection, (const char*)pPacket->pData, (int)pPacket->wLen, 0);
- if (nSendResult != SOCKET_ERROR)
- break;
-
- Sleep(1000);
- }
-
- // Send error
- if (nSendResult == SOCKET_ERROR) // thread stops automatically
- ppro->debugLogA("Your connection with the ICQ avatar server was abortively closed");
- else {
- lResult = 1; // packet sent successfully
-
- mir_cslock rlck(m_ratesMutex);
- if (m_rates)
- m_rates->packetSent(pPacket);
- }
- }
- else ppro->debugLogA("Error: Failed to send packet (no connection)");
-
- SAFE_FREE((void**)&pPacket->pData);
-
- return lResult;
-}
-
-int avatars_server_connection::handleServerPackets(BYTE *buf, size_t buflen)
-{
- BYTE channel;
- WORD sequence;
- size_t datalen, bytesUsed = 0;
-
- while (buflen > 0) {
- // All FLAPS begin with 0x2a
- if (*buf++ != FLAP_MARKER)
- break;
-
- if (buflen < 6)
- break;
-
- unpackByte(&buf, &channel);
- unpackWord(&buf, &sequence);
- unpackWord(&buf, &datalen);
-
- if (buflen < 6 + datalen)
- break;
-
- ppro->debugLogA("Server FLAP: Channel %u, Seq %u, Length %u bytes", channel, sequence, datalen);
-
- switch (channel) {
- case ICQ_LOGIN_CHAN:
- handleLoginChannel(buf);
- break;
-
- case ICQ_DATA_CHAN:
- handleDataChannel(buf, datalen);
- break;
-
- default:
- ppro->debugLogA("Warning: Unhandled Server FLAP Channel: Channel %u, Seq %u, Length %u bytes", channel, sequence, datalen);
- break;
- }
-
- /* Increase pointers so we can check for more FLAPs */
- buf += datalen;
- buflen -= (datalen + 6);
- bytesUsed += (datalen + 6);
- }
-
- return (int)bytesUsed;
-}
-
-void avatars_server_connection::handleLoginChannel(BYTE *buf)
-{
- if (*(DWORD*)buf == 0x1000000) { // here check if we received SRV_HELLO
- wLocalSequence = generate_flap_sequence();
-
- icq_packet packet;
- serverCookieInit(&packet, (LPBYTE)pCookie, wCookieLen);
- sendServerPacket(&packet);
-
- ppro->debugLogA("Sent CLI_IDENT to %s", "avatar server");
-
- SAFE_FREE((void**)&pCookie);
- wCookieLen = 0;
- }
- else ppro->debugLogA("Invalid Server response, Channel 1.");
-}
-
-void avatars_server_connection::handleDataChannel(BYTE *buf, size_t datalen)
-{
- snac_header snacHeader = { 0 };
- if (!unpackSnacHeader(&snacHeader, &buf, &datalen) || !snacHeader.bValid)
- ppro->debugLogA("Error: Failed to parse SNAC header");
- else {
- if (snacHeader.wFlags & 0x8000)
- ppro->debugLogA(" Received SNAC(x%02X,x%02X), version %u", snacHeader.wFamily, snacHeader.wSubtype, snacHeader.wVersion);
- else
- ppro->debugLogA(" Received SNAC(x%02X,x%02X)", snacHeader.wFamily, snacHeader.wSubtype);
-
- switch (snacHeader.wFamily) {
- case ICQ_SERVICE_FAMILY:
- handleServiceFam(buf, datalen, &snacHeader);
- break;
-
- case ICQ_AVATAR_FAMILY:
- handleAvatarFam(buf, datalen, &snacHeader);
- break;
-
- default:
- ppro->debugLogA("Ignoring SNAC(x%02X,x%02X) - FAMILYx%02X not implemented", snacHeader.wFamily, snacHeader.wSubtype, snacHeader.wFamily);
- break;
- }
- }
-}
-
-void avatars_server_connection::handleServiceFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader)
-{
- icq_packet packet;
-
- switch (pSnacHeader->wSubtype) {
- case ICQ_SERVER_READY:
- ppro->debugLogA("Server is ready and is requesting my Family versions");
- ppro->debugLogA("Sending my Families");
-
- // Miranda mimics the behaviour of Icq5
- serverPacketInit(&packet, 18);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_FAMILIES);
- packDWord(&packet, 0x00010004);
- packDWord(&packet, 0x00100001);
- sendServerPacket(&packet);
- break;
-
- case ICQ_SERVER_FAMILIES2:
- /* This is a reply to CLI_FAMILIES and it tells the client which families and their versions that this server understands.
- * We send a rate request packet */
- ppro->debugLogA("Server told me his Family versions");
- ppro->debugLogA("Requesting Rate Information");
-
- serverPacketInit(&packet, 10);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_REQ_RATE_INFO);
- sendServerPacket(&packet);
- break;
-
- case ICQ_SERVER_RATE_INFO:
- ppro->debugLogA("Server sent Rate Info");
-
- /* init rates management */
- m_rates = new rates(ppro, pBuffer, wBufferLength);
-
- /* ack rate levels */
- ppro->debugLogA("Sending Rate Info Ack");
-
- m_rates->initAckPacket(&packet);
- sendServerPacket(&packet);
-
- // send cli_ready
- serverPacketInit(&packet, 26);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_READY);
- packDWord(&packet, 0x00010004); // mimic ICQ 6
- packDWord(&packet, 0x0010164f);
- packDWord(&packet, 0x00100001);
- packDWord(&packet, 0x0010164f);
- sendServerPacket(&packet);
-
- isActive = TRUE; // we are ready to process requests
- isLoggedIn = TRUE;
-
- ppro->debugLogA(" *** Yeehah, login sequence complete");
- break;
-
- default:
- ppro->debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_SERVICE_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
-
-void avatars_server_connection::handleAvatarFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader)
-{
- cookie_avatar *pCookieData;
-
- switch (pSnacHeader->wSubtype) {
- case ICQ_AVATAR_GET_REPLY: // received avatar data, store to file
- // handle new avatar, notify
- if (ppro->FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookieData)) {
- BYTE bResult;
- {
- // remove from active request list
- mir_cslock l(ppro->m_avatarsMutex);
- for (int i = 0; i < runCount; i++) { // look for our record
- if (runContact[i] == pCookieData->hContact) { // found, remove
- runContact[i] = runContact[runCount - 1];
- runTime[i] = runTime[runCount - 1];
- runCount--;
- break;
- }
- }
- }
-
- PROTO_AVATAR_INFORMATION ai = { 0 };
- ai.format = PA_FORMAT_JPEG; // this is for error only
- ai.hContact = pCookieData->hContact;
- mir_wstrncpy(ai.filename, pCookieData->szFile, _countof(ai.filename));
- AddAvatarExt(PA_FORMAT_JPEG, ai.filename);
-
- ppro->FreeCookie(pSnacHeader->dwRef);
-
- BYTE len;
-
- unpackByte(&pBuffer, &len);
- if (wBufferLength < ((pCookieData->hashlen) << 1) + 4 + len) {
- ppro->debugLogA("Received invalid avatar reply.");
-
- ppro->ProtoBroadcastAck(pCookieData->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, (HANDLE)&ai, 0);
-
- SAFE_FREE(&pCookieData->szFile);
- SAFE_FREE((void**)&pCookieData->hash);
- SAFE_FREE((void**)&pCookieData);
- break;
- }
-
- pBuffer += len;
- pBuffer += pCookieData->hashlen;
- unpackByte(&pBuffer, &bResult);
- pBuffer += pCookieData->hashlen;
-
- size_t datalen;
- unpackWord(&pBuffer, &datalen);
-
- wBufferLength -= 4 + len + (pCookieData->hashlen << 1);
- if (datalen > wBufferLength) {
- datalen = wBufferLength;
- ppro->debugLogA("Avatar reply broken, trying to do my best.");
- }
-
- if (datalen > 4) { // store to file...
- int aValid = 1;
-
- if (pCookieData->hashlen == 0x14 && pCookieData->hash[3] == 0x10 && ppro->getByte("StrictAvatarCheck", DEFAULT_AVATARS_CHECK)) { // check only standard hashes
- mir_md5_state_t state;
- BYTE digest[16];
-
- mir_md5_init(&state);
- mir_md5_append(&state, (const BYTE *)pBuffer, (int)datalen);
- mir_md5_finish(&state, digest);
- // check if received data corresponds to specified hash
- if (memcmp(pCookieData->hash + 4, digest, 0x10)) aValid = 0;
- }
-
- if (aValid) {
- ppro->debugLogA("Received user avatar, storing (%d bytes).", datalen);
-
- const wchar_t *ptszExt;
- int dwPaFormat = ProtoGetBufferFormat(pBuffer, &ptszExt);
- wchar_t tszImageFile[MAX_PATH];
- mir_snwprintf(tszImageFile, L"%s%s", pCookieData->szFile, ptszExt);
-
- ppro->setByte(pCookieData->hContact, "AvatarType", (BYTE)dwPaFormat);
- ai.format = dwPaFormat; // set the format
- mir_wstrncpy(ai.filename, tszImageFile, _countof(ai.filename));
-
- int out = _wopen(tszImageFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE);
- if (out != -1) {
- _write(out, pBuffer, (int)datalen);
- _close(out);
-
- if (!pCookieData->hContact) { // our avatar, set filename
- wchar_t tmp[MAX_PATH * 2];
- PathToRelativeW(tszImageFile, tmp);
- ppro->setWString(NULL, "AvatarFile", tmp);
- }
- else { // contact's avatar set hash
- DBVARIANT dbv = { DBVT_DELETED };
- if (!ppro->getSetting(pCookieData->hContact, "AvatarHash", &dbv)) {
- if (ppro->setSettingBlob(pCookieData->hContact, "AvatarSaved", dbv.pbVal, dbv.cpbVal))
- ppro->debugLogA("Failed to set file hash.");
-
- db_free(&dbv);
- }
- else {
- ppro->debugLogA("Warning: DB error (no hash in DB).");
- // the hash was lost, try to fix that
- if (ppro->setSettingBlob(pCookieData->hContact, "AvatarSaved", pCookieData->hash, (int)pCookieData->hashlen) ||
- ppro->setSettingBlob(pCookieData->hContact, "AvatarHash", pCookieData->hash, (int)pCookieData->hashlen)) {
- ppro->debugLogA("Failed to save avatar hash to DB");
- }
- }
- }
-
- ppro->ProtoBroadcastAck(pCookieData->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&ai, 0);
- }
- }
- else { // avatar is broken
- ppro->debugLogA("Error: Avatar data does not match avatar hash, ignoring.");
-
- if (pCookieData->hContact) {
- avatars_request *ar = new avatars_request(ART_BLOCK);
- ar->hContact = pCookieData->hContact;
- ar->timeOut = GetTickCount() + 14400000; // do not allow re-request four hours
-
- mir_cslock l(ppro->m_avatarsMutex);
- ppro->m_arAvatars.insert(ar);
- }
- ppro->ProtoBroadcastAck(pCookieData->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, (HANDLE)&ai, 0);
- }
- }
- else { // the avatar is empty
- ppro->debugLogA("Received empty avatar, nothing written (error 0x%x).", bResult);
- ppro->ProtoBroadcastAck(pCookieData->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, (HANDLE)&ai, 0);
- }
- SAFE_FREE(&pCookieData->szFile);
- SAFE_FREE((void**)&pCookieData->hash);
- SAFE_FREE((void**)&pCookieData);
- }
- else ppro->debugLogA("Warning: Received unexpected Avatar Reply SNAC(x10,x07).");
- break;
-
- case ICQ_AVATAR_UPLOAD_ACK:
- // upload completed, notify
- BYTE res;
- unpackByte(&pBuffer, &res);
- if (!res && (wBufferLength == 0x15)) {
- if (ppro->FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookieData)) // here we store the local hash
- ppro->ReleaseCookie(pSnacHeader->dwRef);
- else
- ppro->debugLogA("Warning: Received unexpected Upload Avatar Reply SNAC(x10,x03).");
- }
- else if (res) {
- ppro->debugLogA("Error uploading avatar to server, #%d", res);
- ppro->icq_LogMessage(LOG_WARNING, LPGEN("Error uploading avatar to server, server refused to accept the image."));
- }
- else ppro->debugLogA("Received invalid upload avatar ack.");
- break;
-
- case ICQ_ERROR:
- if (ppro->FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookieData)) {
- if (pCookieData->dwUin) {
- ppro->debugLogA("Error: Avatar request failed");
- SAFE_FREE(&pCookieData->szFile);
- SAFE_FREE((void**)&pCookieData->hash);
- }
- else ppro->debugLogA("Error: Avatar upload failed");
-
- ppro->ReleaseCookie(pSnacHeader->dwRef);
- }
-
- WORD wError;
- if (wBufferLength >= 2)
- unpackWord(&pBuffer, &wError);
- else
- wError = 0;
-
- ppro->LogFamilyError(ICQ_AVATAR_FAMILY, wError);
- break;
-
- default:
- ppro->debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_AVATAR_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef);
- break;
- }
-}
diff --git a/protocols/IcqOscarJ/src/icq_avatar.h b/protocols/IcqOscarJ/src/icq_avatar.h
deleted file mode 100644
index 6b9f935a69..0000000000
--- a/protocols/IcqOscarJ/src/icq_avatar.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Avatars connection support declarations
-// -----------------------------------------------------------------------------
-
-#ifndef __ICQ_AVATAR_H
-#define __ICQ_AVATAR_H
-
-extern BYTE hashEmptyAvatar[9];
-
-#define AVATAR_HASH_MINI 0x00
-#define AVATAR_HASH_STATIC 0x01
-#define AVATAR_HASH_FLASH 0x08
-#define AVATAR_HASH_PHOTO 0x0C
-
-struct CIcqProto;
-
-class avatars_server_connection : public MZeroedObject
-{
- CIcqProto *ppro;
- HNETLIBCONN hConnection; // handle to the connection
- HANDLE hPacketRecver;
- WORD wLocalSequence;
- mir_cs localSeqMutex, connMutex;
-
- BOOL isLoggedIn;
- BOOL isActive;
- BOOL stopThread; // horrible, but simple - signal for thread to stop
-
- char *pCookie; // auth to server
- size_t wCookieLen;
-
- int sendServerPacket(icq_packet *pPacket);
-
- int handleServerPackets(BYTE *buf, size_t buflen);
-
- void handleLoginChannel(BYTE *buf);
- void handleDataChannel(BYTE *buf, size_t datalen);
-
- void handleServiceFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader);
- void handleAvatarFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader);
-
- rates *m_rates;
- mir_cs m_ratesMutex;
-
- MCONTACT runContact[4];
- DWORD runTime[4];
- int runCount;
- void checkRequestQueue();
-
-public:
- avatars_server_connection(CIcqProto *ppro, HNETLIBCONN hConnection, char *pCookie, size_t wCookieLen);
- virtual ~avatars_server_connection();
-
- void connectionThread();
- void closeConnection();
- void shutdownConnection();
-
- __inline mir_cs& getLock() { return connMutex; }
- __inline BOOL isPending() { return !isLoggedIn; };
- __inline BOOL isReady() { return isLoggedIn && isActive && !stopThread; };
-
- DWORD sendGetAvatarRequest(MCONTACT hContact, DWORD dwUin, char *szUid, const BYTE *hash, size_t hashlen, const wchar_t *file);
- DWORD sendUploadAvatarRequest(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen);
-};
-
-struct avatars_request : public MZeroedObject
-{
- int type;
- MCONTACT hContact;
- DWORD dwUin;
- uid_str szUid;
- BYTE *hash;
- size_t hashlen;
- wchar_t *szFile;
- BYTE *pData;
- size_t cbData;
- WORD wRef;
- DWORD timeOut;
-
-public:
- avatars_request(int type);
- virtual ~avatars_request();
-};
-
-#define ART_GET 1
-#define ART_UPLOAD 2
-#define ART_BLOCK 4
-
-void AddAvatarExt(int dwFormat, wchar_t *pszDest);
-
-BYTE* calcMD5HashOfFile(const wchar_t *szFile);
-
-#endif /* __ICQ_AVATAR_H */
diff --git a/protocols/IcqOscarJ/src/icq_clients.cpp b/protocols/IcqOscarJ/src/icq_clients.cpp
deleted file mode 100644
index 658a963d15..0000000000
--- a/protocols/IcqOscarJ/src/icq_clients.cpp
+++ /dev/null
@@ -1,1007 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Provides capability & signature based client detection
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-const capstr capShortCaps = { 0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; // CAP_AIM_BUDDYICON
-
-static const char* makeClientVersion(char *szBuf, const char *szClient, unsigned v1, unsigned v2, unsigned v3, unsigned v4)
-{
- if (v4)
- mir_snprintf(szBuf, 64, "%s%u.%u.%u.%u", szClient, v1, v2, v3, v4);
- else if (v3)
- mir_snprintf(szBuf, 64, "%s%u.%u.%u", szClient, v1, v2, v3);
- else
- mir_snprintf(szBuf, 64, "%s%u.%u", szClient, v1, v2);
-
- return szBuf;
-}
-
-static void verToStr(char *szStr, int v)
-{
- char szVer[64];
- makeClientVersion(szVer, "", (v >> 24) & 0x7F, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
- mir_strcat(szStr, szVer);
- if (v & 0x80000000)
- mir_strcat(szStr, " alpha");
-}
-
-static char* MirandaVersionToStringEx(char* szStr, int bUnicode, const char* szPlug, int v, int m)
-{
- if (!v) // this is not Miranda
- return nullptr;
-
- mir_strcpy(szStr, "Miranda IM ");
-
- if (!m && v == 1)
- verToStr(szStr, 0x80010200);
- else if (!m && (v & 0x7FFFFFFF) <= 0x030301)
- verToStr(szStr, v);
- else {
- if (m) {
- verToStr(szStr, m);
- mir_strcat(szStr, " ");
- }
- if (bUnicode)
- mir_strcat(szStr, "Unicode ");
-
- mir_strcat(szStr, "(");
- mir_strcat(szStr, szPlug);
- mir_strcat(szStr, " v");
- verToStr(szStr, v);
- mir_strcat(szStr, ")");
- }
-
- return szStr;
-}
-
-char* MirandaModToString(char* szStr, capstr* capId, int bUnicode, const char* szModName)
-{
- // decode icqj mod version
- DWORD mver = (*capId)[0x4] << 0x18 | (*capId)[0x5] << 0x10 | (*capId)[0x6] << 8 | (*capId)[0x7];
- DWORD iver = (*capId)[0x8] << 0x18 | (*capId)[0x9] << 0x10 | (*capId)[0xA] << 8 | (*capId)[0xB];
- DWORD scode = (*capId)[0xC] << 0x18 | (*capId)[0xD] << 0x10 | (*capId)[0xE] << 8 | (*capId)[0xF];
-
- char *szClient = MirandaVersionToStringEx(szStr, bUnicode, szModName, iver, mver);
- if (scode == 0x5AFEC0DE)
- mir_strcat(szClient, " + SecureIM");
-
- return szClient;
-}
-
-const capstr capMirandaIm = { 'M', 'i', 'r', 'a', 'n', 'd', 'a', 'M', 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capMirandaNg = { 'M', 'i', 'r', 'a', 'n', 'd', 'a', 'N', 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capIcqJs7 = { 'i', 'c', 'q', 'j', ' ', 'S', 'e', 'c', 'u', 'r', 'e', ' ', 'I', 'M', 0, 0 };
-const capstr capIcqJSin = { 's', 'i', 'n', 'j', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Miranda ICQJ S!N
-const capstr capIcqJp = { 'i', 'c', 'q', 'p', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capAimOscar = { 'M', 'i', 'r', 'a', 'n', 'd', 'a', 'A', 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capMimMobile = { 'M', 'i', 'r', 'a', 'n', 'd', 'a', 'M', 'o', 'b', 'i', 'l', 'e', 0, 0, 0 };
-const capstr capMimPack = { 'M', 'I', 'M', '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Custom Miranda Pack
-const capstr capTrillian = { 0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09 };
-const capstr capTrilCrypt = { 0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb, 0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00 };
-const capstr capSim = { 'S', 'I', 'M', ' ', 'c', 'l', 'i', 'e', 'n', 't', ' ', ' ', 0, 0, 0, 0 };
-const capstr capSimOld = { 0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x00 };
-const capstr capLicq = { 'L', 'i', 'c', 'q', ' ', 'c', 'l', 'i', 'e', 'n', 't', ' ', 0, 0, 0, 0 };
-const capstr capKopete = { 'K', 'o', 'p', 'e', 't', 'e', ' ', 'I', 'C', 'Q', ' ', ' ', 0, 0, 0, 0 };
-const capstr capmIcq = { 'm', 'I', 'C', 'Q', ' ', 0xA9, ' ', 'R', '.', 'K', '.', ' ', 0, 0, 0, 0 };
-const capstr capClimm = { 'c', 'l', 'i', 'm', 'm', 0xA9, ' ', 'R', '.', 'K', '.', ' ', 0, 0, 0, 0 };
-const capstr capAndRQ = { '&', 'R', 'Q', 'i', 'n', 's', 'i', 'd', 'e', 0, 0, 0, 0, 0, 0, 0 };
-const capstr capRAndQ = { 'R', '&', 'Q', 'i', 'n', 's', 'i', 'd', 'e', 0, 0, 0, 0, 0, 0, 0 };
-const capstr capIMadering = { 'I', 'M', 'a', 'd', 'e', 'r', 'i', 'n', 'g', ' ', 'C', 'l', 'i', 'e', 'n', 't' };
-const capstr capmChat = { 'm', 'C', 'h', 'a', 't', ' ', 'i', 'c', 'q', ' ', 0, 0, 0, 0, 0, 0 };
-const capstr capJimm = { 'J', 'i', 'm', 'm', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capCorePager = { 'C', 'O', 'R', 'E', ' ', 'P', 'a', 'g', 'e', 'r', 0, 0, 0, 0, 0, 0 };
-const capstr capDiChat = { 'D', '[', 'i', ']', 'C', 'h', 'a', 't', ' ', 0, 0, 0, 0, 0, 0, 0 };
-const capstr capVmIcq = { 'V', 'm', 'I', 'C', 'Q', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capSmapeR = { 'S', 'm', 'a', 'p', 'e', 'r', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capAnastasia = { 0x44, 0xE5, 0xBF, 0xCE, 0xB0, 0x96, 0xE5, 0x47, 0xBD, 0x65, 0xEF, 0xD6, 0xA3, 0x7E, 0x36, 0x02 };
-const capstr capPalmJicq = { 'J', 'I', 'C', 'Q', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capInluxMsgr = { 0xA7, 0xE4, 0x0A, 0x96, 0xB3, 0xA0, 0x47, 0x9A, 0xB8, 0x45, 0xC9, 0xE4, 0x67, 0xC5, 0x6B, 0x1F };
-const capstr capYapp = { 'Y', 'a', 'p', 'p', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capMipClient = { 0x4d, 0x49, 0x50, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x00, 0x00, 0x00, 0x00 };
-const capstr capPigeon = { 'P', 'I', 'G', 'E', 'O', 'N', '!', 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capDigsbyBeta = { 0x09, 0x46, 0x01, 0x05, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00 };
-const capstr capDigsby = { 'd', 'i', 'g', 's', 'b', 'y', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capJapp = { 0x6a, 0x61, 0x70, 0x70, 0xa9, 0x20, 0x62, 0x79, 0x20, 0x53, 0x65, 0x72, 0x67, 0x6f, 0x00, 0x00 };
-const capstr capNaim = { 0xFF, 0xFF, 0xFF, 0xFF, 'n', 'a', 'i', 'm', 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capCitron = { 0x09, 0x19, 0x19, 0x82, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 };
-const capstr capQip = { 0x56, 0x3F, 0xC8, 0x09, 0x0B, 0x6F, 0x41, 'Q', 'I', 'P', ' ', '2', '0', '0', '5', 'a' };
-const capstr capQipPDA = { 0x56, 0x3F, 0xC8, 0x09, 0x0B, 0x6F, 0x41, 'Q', 'I', 'P', ' ', ' ', ' ', ' ', ' ', '!' };
-const capstr capQipSymbian = { 0x51, 0xAD, 0xD1, 0x90, 0x72, 0x04, 0x47, 0x3D, 0xA1, 0xA1, 0x49, 0xF4, 0xA3, 0x97, 0xA4, 0x1F };
-const capstr capQipIphone = { 0x60, 0xDE, 0x5C, 0x8A, 0xDF, 0x8C, 0x4E, 0x1D, 0xA4, 0xC8, 0xBC, 0x3B, 0xD9, 0x79, 0x4D, 0xD8 };
-const capstr capQipMobile = { 0xB0, 0x82, 0x62, 0xF6, 0x7F, 0x7C, 0x45, 0x61, 0xAD, 0xC1, 0x1C, 0x6D, 0x75, 0x70, 0x5E, 0xC5 };
-const capstr capQipInfium = { 0x7C, 0x73, 0x75, 0x02, 0xC3, 0xBE, 0x4F, 0x3E, 0xA6, 0x9F, 0x01, 0x53, 0x13, 0x43, 0x1E, 0x1A };
-const capstr capQip2010 = { 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x0A, 0x03, 0x0B, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, 0x00 };
-const capstr capQip2012 = { 0x7F, 0x7F, 0x7C, 0x7D, 0x7E, 0x7F, 0x0A, 0x03, 0x0B, 0x04, 0x01, 0x53, 0x13, 0x43, 0x1E, 0x1A };
-const capstr capIm2 = { 0x74, 0xED, 0xC3, 0x36, 0x44, 0xDF, 0x48, 0x5B, 0x8B, 0x1C, 0x67, 0x1A, 0x1F, 0x86, 0x09, 0x9F }; // IM2 Ext Msg
-const capstr capQutIm = { 'q', 'u', 't', 'i', 'm', 0x30, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-const capstr capBayan = { 'b', 'a', 'y', 'a', 'n', 'I', 'C', 'Q', 0, 0, 0, 0, 0, 0, 0, 0 };
-const capstr capJabberJIT = { 'J', 'I', 'T', ' ', 0x76, 0x2E, 0x31, 0x2E, 0x78, 0x2E, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00 };
-const capstr capIcqKid2 = { 'I', 'c', 'q', 'K', 'i', 'd', '2', 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-const capstr capWebIcqPro = { 'W', 'e', 'b', 'I', 'c', 'q', 'P', 'r', 'o', ' ', 0, 0, 0, 0, 0, 0 };
-const capstr capJasmine = { 0x4A, 0x61, 0x73, 0x6D, 0x69, 0x6E, 0x65, 0x20, 0x76, 0x65, 0x72, 0xFF, 0x00, 0x00, 0x00, 0x00 };
-const capstr capMraJava = { 0x4a, 0x32, 0x4d, 0x45, 0x20, 0x6d, 0x40, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00 };
-const capstr capMacIcq = { 0xdd, 0x16, 0xf2, 0x02, 0x84, 0xe6, 0x11, 0xd4, 0x90, 0xdb, 0x00, 0x10, 0x4b, 0x9b, 0x4b, 0x7d };
-const capstr capIs2001 = { 0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8, 0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf };
-const capstr capIs2002 = { 0x10, 0xcf, 0x40, 0xd1, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 };
-const capstr capComm20012 = { 0xa0, 0xe9, 0x3f, 0x37, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 };
-const capstr capStrIcq = { 0xa0, 0xe9, 0x3f, 0x37, 0x4f, 0xe9, 0xd3, 0x11, 0xbc, 0xd2, 0x00, 0x04, 0xac, 0x96, 0xdd, 0x96 };
-const capstr capIcqLiteNew = { 0xc8, 0x95, 0x3a, 0x9f, 0x21, 0xf1, 0x4f, 0xaa, 0xb0, 0xb2, 0x6d, 0xe6, 0x63, 0xab, 0xf5, 0xb7 };
-const capstr capXtrazVideo = { 0x17, 0x8C, 0x2D, 0x9B, 0xDA, 0xA5, 0x45, 0xBB, 0x8D, 0xDB, 0xF3, 0xBD, 0xBD, 0x53, 0xA1, 0x0A };
-const capstr capOscarChat = { 0x74, 0x8F, 0x24, 0x20, 0x62, 0x87, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 };
-const capstr capUim = { 0xA7, 0xE4, 0x0A, 0x96, 0xB3, 0xA0, 0x47, 0x9A, 0xB8, 0x45, 0xC9, 0xE4, 0x67, 0xC5, 0x6B, 0x1F };
-const capstr capRambler = { 0x7E, 0x11, 0xB7, 0x78, 0xA3, 0x53, 0x49, 0x26, 0xA8, 0x02, 0x44, 0x73, 0x52, 0x08, 0xC4, 0x2A };
-const capstr capAbv = { 0x00, 0xE7, 0xE0, 0xDF, 0xA9, 0xD0, 0x4F, 0xe1, 0x91, 0x62, 0xC8, 0x90, 0x9A, 0x13, 0x2A, 0x1B };
-const capstr capNetvigator = { 0x4C, 0x6B, 0x90, 0xA3, 0x3D, 0x2D, 0x48, 0x0E, 0x89, 0xD6, 0x2E, 0x4B, 0x2C, 0x10, 0xD9, 0x9F };
-const capstr captZers = { 0xb2, 0xec, 0x8f, 0x16, 0x7c, 0x6f, 0x45, 0x1b, 0xbd, 0x79, 0xdc, 0x58, 0x49, 0x78, 0x88, 0xb9 }; // CAP_TZERS
-const capstr capSimpLite = { 0x53, 0x49, 0x4D, 0x50, 0x53, 0x49, 0x4D, 0x50, 0x53, 0x49, 0x4D, 0x50, 0x53, 0x49, 0x4D, 0x50 };
-const capstr capSimpPro = { 0x53, 0x49, 0x4D, 0x50, 0x5F, 0x50, 0x52, 0x4F, 0x53, 0x49, 0x4D, 0x50, 0x5F, 0x50, 0x52, 0x4F };
-const capstr capIMsecure = { 'I', 'M', 's', 'e', 'c', 'u', 'r', 'e', 'C', 'p', 'h', 'r', 0x00, 0x00, 0x06, 0x01 }; // ZoneLabs
-const capstr capIMSecKey1 = { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // ZoneLabs
-const capstr capIMSecKey2 = { 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // ZoneLabs
-const capstr capFakeHtml = { 0x01, 0x38, 0xca, 0x7b, 0x76, 0x9a, 0x49, 0x15, 0x88, 0xf2, 0x13, 0xfc, 0x00, 0x97, 0x9e, 0xa8 };
-const capstr capIcqIos = { 0x09, 0x46, 0x13, 0x52, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 'D', 'E', 'S', 'T', 0x00, 0x00 };
-const capstr capIcqAndroid = { 0x09, 0x46, 0x13, 0x53, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 'D', 'E', 'S', 'T', 0x00, 0x00 };
-
-const shortcapstr capAimIcon = { 0x13, 0x46 }; // CAP_AIM_BUDDYICON
-const shortcapstr capAimDirect = { 0x13, 0x45 }; // CAP_AIM_DIRECTIM
-const shortcapstr capAimFileShare = { 0x13, 0x48 }; // CAP_AIM_FILE_SHARE
-const shortcapstr capIcqDevils = { 0x13, 0x4C }; // CAP_DEVILS
-const shortcapstr capAimSmartCaps = { 0x01, 0xFF };
-const shortcapstr capAimLiveVideo = { 0x01, 0x01 }; // CAP_AIM_LIVE_VIDEO
-const shortcapstr capAimLiveAudio = { 0x01, 0x04 }; // CAP_AIM_LIVE_AUDIO
-const shortcapstr capStatusTextAware = { 0x01, 0x0A }; // CAP_HOST_STATUS_TEXT_AWARE
-
-const char* cliLibicq2k = "libicq2000";
-const char* cliLicqVer = "Licq ";
-const char* cliCentericq = "Centericq";
-const char* cliLibicqUTF = "libicq2000 (Unicode)";
-const char* cliTrillian = "Trillian";
-const char* cliTrillian4 = "Trillian Astra";
-const char* cliQip = "QIP %s";
-const char* cliIM2 = "IM2";
-const char* cliSpamBot = "Spam Bot";
-
-const char* CIcqProto::detectUserClient(
- MCONTACT hContact, int nIsICQ, WORD wUserClass, DWORD dwOnlineSince, const char *szCurrentClient,
- WORD wVersion, DWORD dwFT1, DWORD dwFT2, DWORD dwFT3, DWORD dwDirectCookie, DWORD dwWebPort, /* ICQ specific */
- BYTE *caps, size_t wLen, /* Client capabilities */
- BYTE *bClientId, /* Output: detected client-type */
- char *szClientBuf)
-{
- LPCSTR szClient = nullptr;
- int bMirandaIM = FALSE;
-
- *bClientId = CLID_ALTERNATIVE; // Most clients does not tick as MsgIDs
-
- // Is this a Miranda IM client?
- if (dwFT1 == 0xffffffff) {
- if (dwFT2 == 0xffffffff) // This is Gaim not Miranda
- szClient = "Gaim";
- else if (!dwFT2 && wVersion == 7) // This is WebICQ not Miranda
- szClient = "WebICQ";
- else if (!dwFT2 && dwFT3 == 0x3B7248ED) // And this is most probably Spam Bot
- szClient = cliSpamBot;
- else {
- // Yes this is most probably Miranda, get the version info
- szClient = MirandaVersionToStringEx(szClientBuf, 0, "ICQ", dwFT2, 0);
- *bClientId = CLID_MIRANDA;
- bMirandaIM = TRUE;
- }
- }
- else if (dwFT1 == 0x7fffffff) {
- // This is Miranda with unicode core
- szClient = MirandaVersionToStringEx(szClientBuf, 1, "ICQ", dwFT2, 0);
- *bClientId = CLID_MIRANDA;
- bMirandaIM = TRUE;
- }
- else if ((dwFT1 & 0xFF7F0000) == 0x7D000000) {
- // This is probably an Licq client
- DWORD ver = dwFT1 & 0xFFFF;
-
- szClient = makeClientVersion(szClientBuf, cliLicqVer, ver / 1000, (ver / 10) % 100, ver % 10, 0);
- if (dwFT1 & 0x00800000)
- mir_strcat(szClientBuf, "/SSL");
- }
- else if (dwFT1 == 0xffffff8f)
- szClient = "StrICQ";
- else if (dwFT1 == 0xffffff42)
- szClient = "mICQ";
- else if (dwFT1 == 0xffffffbe) {
- unsigned ver1 = (dwFT2 >> 24) & 0xFF;
- unsigned ver2 = (dwFT2 >> 16) & 0xFF;
- unsigned ver3 = (dwFT2 >> 8) & 0xFF;
- szClient = makeClientVersion(szClientBuf, "Alicq ", ver1, ver2, ver3, 0);
- }
- else if (dwFT1 == 0xFFFFFF7F)
- szClient = "&RQ";
- else if (dwFT1 == 0xFFFFF666) {
- // this is R&Q (Rapid Edition)
- mir_snprintf(szClientBuf, 64, "R&Q %u", (unsigned)dwFT2);
- szClient = szClientBuf;
- }
- else if (dwFT1 == 0xFFFFFFAB)
- szClient = "YSM";
- else if (dwFT1 == 0x04031980)
- szClient = "vICQ";
- else if ((dwFT1 == 0x3AA773EE) && (dwFT2 == 0x3AA66380))
- szClient = cliLibicq2k;
- else if (dwFT1 == 0x3B75AC09)
- szClient = cliTrillian;
- else if (dwFT1 == 0x3BA8DBAF) { // FT2: 0x3BEB5373; FT3: 0x3BEB5262;
- if (wVersion == 2)
- szClient = "stICQ";
- }
- else if (dwFT1 == 0xFFFFFFFE && dwFT3 == 0xFFFFFFFE)
- szClient = "Jimm";
- else if (dwFT1 == 0x3FF19BEB && dwFT3 == 0x3FF19BEB)
- szClient = cliIM2;
- else if (dwFT1 == 0xDDDDEEFF && !dwFT2 && !dwFT3)
- szClient = "SmartICQ";
- else if ((dwFT1 & 0xFFFFFFF0) == 0x494D2B00 && !dwFT2 && !dwFT3)
- // last byte of FT1: (5 = Win32, 3 = SmartPhone, Pocket PC)
- szClient = "IM+";
- else if (dwFT1 == 0x3B4C4C0C && !dwFT2 && dwFT3 == 0x3B7248ed)
- szClient = "KXicq2";
- else if (dwFT1 == 0x66666666 && dwFT3 == 0x66666666) {
- // http://darkjimm.ucoz.ru/
- if (dwFT2 == 0x10000) {
- mir_strcpy(szClientBuf, "D[i]Chat v.");
- mir_strcat(szClientBuf, "0.1a");
- }
- else {
- makeClientVersion(szClientBuf, "D[i]Chat v.", (dwFT2 >> 8) & 0x0F, (dwFT2 >> 4) & 0x0F, 0, 0);
- if ((dwFT2 & 0x0F) == 1)
- mir_strcat(szClientBuf, " alpha");
- else if ((dwFT2 & 0x0F) == 2)
- mir_strcat(szClientBuf, " beta");
- else if ((dwFT2 & 0x0F) == 3)
- mir_strcat(szClientBuf, " final");
- }
- szClient = szClientBuf;
- }
- else if (dwFT1 == dwFT2 && dwFT2 == dwFT3 && wVersion == 8) {
- if ((dwFT1 < dwOnlineSince + 3600) && (dwFT1 > (dwOnlineSince - 3600)))
- szClient = cliSpamBot;
- }
- else if (!dwFT1 && !dwFT2 && !dwFT3 && !wVersion && !wLen && dwWebPort == 0x75BB)
- szClient = cliSpamBot;
- else if (dwFT1 == 0x44F523B0 && dwFT2 == 0x44F523A6 && dwFT3 == 0x44F523A6 && wVersion == 8)
- szClient = "Virus";
-
- // capabilities based detection
- capstr *capId;
- char ver[16];
-
- if (nIsICQ && caps) {
- // check capabilities for client identification
- if (capId = MatchCapability(caps, wLen, &capMirandaIm, 8)) {
- // new Miranda Signature
- DWORD iver = (*capId)[0xC] << 0x18 | (*capId)[0xD] << 0x10 | (*capId)[0xE] << 8 | (*capId)[0xF];
- DWORD mver = (*capId)[0x8] << 0x18 | (*capId)[0x9] << 0x10 | (*capId)[0xA] << 8 | (*capId)[0xB];
-
- szClient = MirandaVersionToStringEx(szClientBuf, dwFT1 == 0x7fffffff, "ICQ", iver, mver);
-
- if (MatchCapability(caps, wLen, &capIcqJs7, 0x4)) {
- // detect mod
- mir_strcat(szClientBuf, " (s7 & sss)");
- if (MatchCapability(caps, wLen, &capIcqJs7, 0xE))
- mir_strcat(szClientBuf, " + SecureIM");
- }
- else if ((dwFT1 & 0x7FFFFFFF) == 0x7FFFFFFF) {
- if (MatchCapability(caps, wLen, &capMimMobile))
- mir_strcat(szClientBuf, " (Mobile)");
-
- if (dwFT3 == 0x5AFEC0DE)
- mir_strcat(szClientBuf, " + SecureIM");
- }
- *bClientId = CLID_MIRANDA;
- bMirandaIM = TRUE;
- }
- else if (capId = MatchCapability(caps, wLen, &capMirandaNg, 8)) {
- WORD v[4];
- BYTE *buf = *capId + 8;
- unpackWord(&buf, &v[0]); unpackWord(&buf, &v[1]); unpackWord(&buf, &v[2]); unpackWord(&buf, &v[3]);
- mir_snprintf(szClientBuf, MAX_PATH, "Miranda NG ICQ %d.%d.%d.%d", v[0], v[1], v[2], v[3]);
-
- szClient = szClientBuf;
- if ((dwFT1 & 0x7FFFFFFF) == 0x7FFFFFFF && dwFT3 == 0x5AFEC0DE)
- mir_strcat(szClientBuf, " + SecureIM");
-
- *bClientId = CLID_MIRANDA;
- bMirandaIM = TRUE;
- }
- else if (capId = MatchCapability(caps, wLen, &capIcqJs7, 4)) {
- // detect newer icqj mod
- szClient = MirandaModToString(szClientBuf, capId, dwFT3 == 0x80000000, "ICQ S7 & SSS");
- bMirandaIM = TRUE;
- }
- else if (capId = MatchCapability(caps, wLen, &capIcqJSin, 4)) {
- // detect newer icqj mod
- szClient = MirandaModToString(szClientBuf, capId, dwFT3 == 0x80000000, "ICQ S!N");
- bMirandaIM = TRUE;
- }
- else if (capId = MatchCapability(caps, wLen, &capIcqJp, 4)) {
- // detect icqj plus mod
- szClient = MirandaModToString(szClientBuf, capId, dwFT3 == 0x80000000, "ICQ Plus");
- bMirandaIM = TRUE;
- }
- else if (capId = MatchCapability(caps, wLen, &capJasmine, 12)) {
- BYTE *p = (*capId) + 12;
- szClient = makeClientVersion(szClientBuf, "Jasmine IM v", p[0], p[1], p[2], p[3]);
- }
- else if (capId = MatchCapability(caps, wLen, &capMraJava, 12)) {
- unsigned ver1 = (*capId)[13];
- unsigned ver2 = (*capId)[14];
-
- szClient = makeClientVersion(szClientBuf, "Mail.ru Agent (Java) v", ver1, ver2, 0, 0);
- }
- else if (MatchCapability(caps, wLen, &capTrillian) || MatchCapability(caps, wLen, &capTrilCrypt)) {
- // this is Trillian, check for new versions
- if (CheckContactCapabilities(hContact, CAPF_RTF)) {
- if (CheckContactCapabilities(hContact, CAPF_OSCAR_FILE))
- szClient = cliTrillian4;
- else {
- // workaroud for a bug in Trillian - make it receive msgs, other features will not work!
- ClearContactCapabilities(hContact, CAPF_SRV_RELAY);
- szClient = "Trillian v3";
- }
- }
- else if (MatchCapability(caps, wLen, &capFakeHtml) || CheckContactCapabilities(hContact, CAPF_OSCAR_FILE))
- szClient = cliTrillian4;
- else
- szClient = cliTrillian;
- }
- else if ((capId = MatchCapability(caps, wLen, &capSimOld, 0xF)) && ((*capId)[0xF] != 0x92 && (*capId)[0xF] >= 0x20 || (*capId)[0xF] == 0)) {
- int hiVer = (((*capId)[0xF]) >> 6) - 1;
- unsigned loVer = (*capId)[0xF] & 0x1F;
-
- if ((hiVer < 0) || ((hiVer == 0) && (loVer == 0)))
- szClient = "Kopete";
- else
- szClient = makeClientVersion(szClientBuf, "SIM ", (unsigned)hiVer, loVer, 0, 0);
- }
- else if (capId = MatchCapability(caps, wLen, &capSim, 0xC)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xD];
- unsigned ver3 = (*capId)[0xE];
- unsigned ver4 = (*capId)[0xF];
-
- szClient = makeClientVersion(szClientBuf, "SIM ", ver1, ver2, ver3, ver4 & 0x0F);
- if (ver4 & 0x80)
- mir_strcat(szClientBuf, "/Win32");
- else if (ver4 & 0x40)
- mir_strcat(szClientBuf, "/MacOS X");
- }
- else if (capId = MatchCapability(caps, wLen, &capLicq, 0xC)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xD] % 100;
- unsigned ver3 = (*capId)[0xE];
-
- szClient = makeClientVersion(szClientBuf, cliLicqVer, ver1, ver2, ver3, 0);
- if ((*capId)[0xF])
- mir_strcat(szClientBuf, "/SSL");
- }
- else if (capId = MatchCapability(caps, wLen, &capKopete, 0xC)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xD];
- unsigned ver3 = (*capId)[0xE];
- unsigned ver4 = (*capId)[0xF];
-
- szClient = makeClientVersion(szClientBuf, "Kopete ", ver1, ver2, ver3, ver4);
- }
- else if (capId = MatchCapability(caps, wLen, &capClimm, 0xC)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xD];
- unsigned ver3 = (*capId)[0xE];
- unsigned ver4 = (*capId)[0xF];
-
- szClient = makeClientVersion(szClientBuf, "climm ", ver1, ver2, ver3, ver4);
- if ((ver1 & 0x80) == 0x80)
- mir_strcat(szClientBuf, " alpha");
- if (dwFT3 == 0x02000020)
- mir_strcat(szClientBuf, "/Win32");
- else if (dwFT3 == 0x03000800)
- mir_strcat(szClientBuf, "/MacOS X");
- }
- else if (capId = MatchCapability(caps, wLen, &capmIcq, 0xC)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xD];
- unsigned ver3 = (*capId)[0xE];
- unsigned ver4 = (*capId)[0xF];
-
- szClient = makeClientVersion(szClientBuf, "mICQ ", ver1, ver2, ver3, ver4);
- if ((ver1 & 0x80) == 0x80)
- mir_strcat(szClientBuf, " alpha");
- }
- // IM2 v2 provides also Aim Icon cap
- else if (MatchCapability(caps, wLen, &capIm2))
- szClient = cliIM2;
- else if (capId = MatchCapability(caps, wLen, &capAndRQ, 9)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xB];
- unsigned ver3 = (*capId)[0xA];
- unsigned ver4 = (*capId)[9];
-
- szClient = makeClientVersion(szClientBuf, "&RQ ", ver1, ver2, ver3, ver4);
- }
- else if (capId = MatchCapability(caps, wLen, &capRAndQ, 9)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xB];
- unsigned ver3 = (*capId)[0xA];
- unsigned ver4 = (*capId)[9];
-
- szClient = makeClientVersion(szClientBuf, "R&Q ", ver1, ver2, ver3, ver4);
- }
- // http://imadering.com
- else if (MatchCapability(caps, wLen, &capIMadering))
- szClient = "IMadering";
- else if (MatchCapability(caps, wLen, &capQipPDA))
- szClient = "QIP PDA (Windows)";
- else if (MatchCapability(caps, wLen, &capQipSymbian))
- szClient = "QIP PDA (Symbian)";
- else if (MatchCapability(caps, wLen, &capQipIphone))
- szClient = "QIP Mobile (IPhone)";
- else if (MatchCapability(caps, wLen, &capQipMobile))
- szClient = "QIP Mobile (Java)";
- else if (MatchCapability(caps, wLen, &capQipInfium)) {
- mir_strcpy(szClientBuf, "QIP Infium");
- if (dwFT1) {
- mir_snprintf(ver, " (%d)", dwFT1);
- mir_strcat(szClientBuf, ver);
- }
- if (dwFT2 == 0x0B)
- mir_strcat(szClientBuf, " Beta");
-
- szClient = szClientBuf;
- }
- else if (MatchCapability(caps, wLen, &capQip2010, 12)) {
- mir_strcpy(szClientBuf, "QIP 2010");
- if (dwFT1) {
- mir_snprintf(ver, " (%d)", dwFT1);
- mir_strcat(szClientBuf, ver);
- }
-
- szClient = szClientBuf;
- }
- else if (MatchCapability(caps, wLen, &capQip2012, 12)) {
- mir_strcpy(szClientBuf, "QIP 2012");
- if (dwFT1) {
- mir_snprintf(ver, " (%d)", dwFT1);
- mir_strcat(szClientBuf, ver);
- }
-
- szClient = szClientBuf;
- }
- else if (capId = MatchCapability(caps, wLen, &capQip, 0xE)) {
- if (dwFT3 == 0x0F)
- mir_strcpy(ver, "2005");
- else
- null_strcpy(ver, (char*)(*capId) + 11, 5);
-
- mir_snprintf(szClientBuf, 64, cliQip, ver);
- if (dwFT1 && dwFT2 == 0x0E) {
- mir_snprintf(ver, " (%d%d%d%d)", dwFT1 >> 0x18, (dwFT1 >> 0x10) & 0xFF, (dwFT1 >> 0x08) & 0xFF, dwFT1 & 0xFF);
- mir_strcat(szClientBuf, ver);
- }
- szClient = szClientBuf;
- }
- else if (capId = MatchCapability(caps, wLen, &capmChat, 0xA)) {
- mir_strcpy(szClientBuf, "mChat ");
- mir_strncat(szClientBuf, (char*)(*capId) + 0xA, 6);
- szClient = szClientBuf;
- }
- else if (capId = MatchCapability(caps, wLen, &capJimm, 5)) {
- mir_strcpy(szClientBuf, "Jimm ");
- mir_strncat(szClientBuf, (char*)(*capId) + 5, 11);
- szClient = szClientBuf;
- }
- // http://corepager.net.ru/index/0-2
- else if (capId = MatchCapability(caps, wLen, &capCorePager, 0xA)) {
- mir_strcpy(szClientBuf, "CORE Pager");
- if (dwFT2 == 0x0FFFF0011 && dwFT3 == 0x1100FFFF && (dwFT1 >> 0x18)) {
- mir_snprintf(ver, " %d.%d", dwFT1 >> 0x18, (dwFT1 >> 0x10) & 0xFF);
- if ((dwFT1 & 0xFF) == 0x0B)
- mir_strcat(ver, " Beta");
- mir_strcat(szClientBuf, ver);
- }
- szClient = szClientBuf;
- }
- // http://darkjimm.ucoz.ru/
- else if (capId = MatchCapability(caps, wLen, &capDiChat, 9)) {
- mir_strcpy(szClientBuf, "D[i]Chat");
- mir_strncat(szClientBuf, (char*)(*capId) + 8, 8);
- szClient = szClientBuf;
- }
- else if (MatchCapability(caps, wLen, &capMacIcq))
- szClient = "ICQ for Mac";
- else if (MatchCapability(caps, wLen, &capUim))
- szClient = "uIM";
- // http://chis.nnov.ru/anastasia
- else if (MatchCapability(caps, wLen, &capAnastasia))
- szClient = "Anastasia";
- // http://www.jsoft.ru
- else if (capId = MatchCapability(caps, wLen, &capPalmJicq, 0xC)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xD];
- unsigned ver3 = (*capId)[0xE];
- unsigned ver4 = (*capId)[0xF];
- szClient = makeClientVersion(szClientBuf, "JICQ ", ver1, ver2, ver3, ver4);
- }
- // http://www.inlusoft.com
- else if (MatchCapability(caps, wLen, &capInluxMsgr))
- szClient = "Inlux Messenger";
- // http://mip.rufon.net
- else if (capId = MatchCapability(caps, wLen, &capMipClient, 0xC)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xD];
- unsigned ver3 = (*capId)[0xE];
- unsigned ver4 = (*capId)[0xF];
- if (ver1 < 30)
- makeClientVersion(szClientBuf, "MIP ", ver1, ver2, ver3, ver4);
- else {
- mir_strcpy(szClientBuf, "MIP ");
- mir_strncat(szClientBuf, (char*)(*capId) + 11, 5);
- }
- szClient = szClientBuf;
- }
- //http://mip.rufon.net - new signature
- else if (capId = MatchCapability(caps, wLen, &capMipClient, 0x04)) {
- mir_strcpy(szClientBuf, "MIP ");
- mir_strncat(szClientBuf, (char*)(*capId) + 4, 12);
- szClient = szClientBuf;
- }
- else if (capId = MatchCapability(caps, wLen, &capVmIcq, 0x06)) {
- mir_strcpy(szClientBuf, "VmICQ");
- mir_strncat(szClientBuf, (char*)(*capId) + 5, 11);
- szClient = szClientBuf;
- }
- // http://www.smape.com/smaper
- else if (capId = MatchCapability(caps, wLen, &capSmapeR, 0x07)) {
- mir_strcpy(szClientBuf, "SmapeR");
- mir_strncat(szClientBuf, (char*)(*capId) + 6, 10);
- szClient = szClientBuf;
- }
- // http://yapp.ru
- else if (capId = MatchCapability(caps, wLen, &capYapp, 0x04)) {
- mir_strcpy(szClientBuf, "Yapp! v");
- mir_strncat(szClientBuf, (char*)(*capId) + 8, 5);
- szClient = szClientBuf;
- }
- // http://www.dibsby.com (newer builds)
- else if (MatchCapability(caps, wLen, &capDigsby, 0x06))
- szClient = "Digsby";
- // http://www.digsby.com - probably by mistake (feature detection as well)
- else if (MatchCapability(caps, wLen, &capDigsbyBeta))
- szClient = "Digsby";
- // http://www.japp.org.ua
- else if (MatchCapability(caps, wLen, &capJapp))
- szClient = "japp";
- // http://pigeon.vpro.ru
- else if (MatchCapability(caps, wLen, &capPigeon, 0x07))
- szClient = "PIGEON!";
- // http://www.qutim.org
- else if (capId = MatchCapability(caps, wLen, &capQutIm, 0x05)) {
- if ((*capId)[0x6] == 0x2E) { // old qutim id
- unsigned ver1 = (*capId)[0x5] - 0x30;
- unsigned ver2 = (*capId)[0x7] - 0x30;
- makeClientVersion(szClientBuf, "qutIM ", ver1, ver2, 0, 0);
- }
- else { // new qutim id
- unsigned ver1 = (*capId)[0x6];
- unsigned ver2 = (*capId)[0x7];
- unsigned ver3 = (*capId)[0x8];
- unsigned ver4 = ((*capId)[0x9] << 8) || (*capId)[0xA];
-
- makeClientVersion(szClientBuf, "qutIM ", ver1, ver2, ver3, ver4);
-
- switch ((*capId)[0x5]) {
- case 'l':
- mir_strcat(szClientBuf, "/Linux");
- break;
- case 'w':
- mir_strcat(szClientBuf, "/Win32");
- break;
- case 'm':
- mir_strcat(szClientBuf, "/MacOS X");
- break;
- }
- }
- szClient = szClientBuf;
- }
- // http://www.barobin.com/bayanICQ.html
- else if (capId = MatchCapability(caps, wLen, &capBayan, 8)) {
- mir_strcpy(szClientBuf, "bayanICQ ");
- mir_strncat(szClientBuf, (char*)(*capId) + 8, 5);
- szClient = szClientBuf;
- }
- else if (capId = MatchCapability(caps, wLen, &capJabberJIT, 0x04))
- szClient = "Jabber ICQ Transport";
- // http://sourceforge.net/projects/icqkid2
- else if (capId = MatchCapability(caps, wLen, &capIcqKid2, 0x07)) {
- unsigned ver1 = (*capId)[0x7];
- unsigned ver2 = (*capId)[0x8];
- unsigned ver3 = (*capId)[0x9];
- unsigned ver4 = (*capId)[0xA];
- szClient = makeClientVersion(szClientBuf, "IcqKid2 v", ver1, ver2, ver3, ver4);
- }
- // http://intrigue.ru/workshop/webicqpro/webicqpro.html
- else if (capId = MatchCapability(caps, wLen, &capWebIcqPro, 0x0A))
- szClient = "WebIcqPro";
- // http://www.citron-im.com
- else if (capId = MatchCapability(caps, wLen, &capCitron))
- szClient = "Citron IM";
- // try to determine which client is behind libicq2000
- else if (szClient == cliLibicq2k) {
- if (CheckContactCapabilities(hContact, CAPF_RTF))
- szClient = cliCentericq; // centericq added rtf capability to libicq2000
- else if (CheckContactCapabilities(hContact, CAPF_UTF))
- szClient = cliLibicqUTF; // IcyJuice added unicode capability to libicq2000
- // others - like jabber transport uses unmodified library, thus cannot be detected
- }
- // THE SIGNATURE DETECTION ENDS HERE, after this only feature default will be detected
- else if (szClient == nullptr) {
- // ZA mangled the version, OMG!
- if (wVersion == 8 && CheckContactCapabilities(hContact, CAPF_XTRAZ) && (MatchCapability(caps, wLen, &capIMSecKey1, 6) || MatchCapability(caps, wLen, &capIMSecKey2, 6)))
- wVersion = ICQ_VERSION;
-
- // try to determine 2001-2003 versions
- if (wVersion == 8 && (MatchCapability(caps, wLen, &capComm20012) || CheckContactCapabilities(hContact, CAPF_SRV_RELAY))) {
- if (MatchCapability(caps, wLen, &capIs2001)) {
- if (!dwFT1 && !dwFT2 && !dwFT3) {
- if (CheckContactCapabilities(hContact, CAPF_RTF))
- szClient = "TICQClient"; // possibly also older GnomeICU
- else
- szClient = "ICQ for Pocket PC";
- }
- else {
- *bClientId = CLID_GENERIC;
- szClient = "ICQ 2001";
- }
- }
- else if (MatchCapability(caps, wLen, &capIs2002)) {
- *bClientId = CLID_GENERIC;
- szClient = "ICQ 2002";
- }
- else if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_RTF)) {
- if (!dwFT1 && !dwFT2 && !dwFT3) {
- if (!dwWebPort)
- szClient = "GnomeICU 0.99.5+"; // no other way
- else
- szClient = "IC@";
- }
- else {
- *bClientId = CLID_GENERIC;
- szClient = "ICQ 2002/2003a";
- }
- }
- // libpurple (e.g. Pidgin 2.7.x)
- else if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_TYPING | CAPF_XTRAZ) &&
- MatchCapability(caps, wLen, &capOscarChat) && MatchShortCapability(caps, wLen, &capAimIcon) &&
- MatchCapability(caps, wLen, &capFakeHtml)) {
- if (MatchShortCapability(caps, wLen, &capAimDirect))
- szClient = "libpurple";
- else
- szClient = "Meebo";
- }
- else if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_TYPING)) {
- if (!dwFT1 && !dwFT2 && !dwFT3)
- szClient = "PreludeICQ";
- }
- }
- else if (wVersion == 8) {
- if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_TYPING) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchShortCapability(caps, wLen, &capAimDirect))
- szClient = "imo.im"; //https://imo.im/ - Web IM
- }
- // try to determine lite versions
- else if (wVersion >= 9) {
- if (CheckContactCapabilities(hContact, CAPF_XTRAZ)) {
- *bClientId = CLID_GENERIC;
- if (CheckContactCapabilities(hContact, CAPF_OSCAR_FILE)) {
- if (MatchCapability(caps, wLen, &captZers)) {
- // capable of tZers ?
- if (MatchCapability(caps, wLen, &capIcqLiteNew) && MatchShortCapability(caps, wLen, &capStatusTextAware) &&
- MatchShortCapability(caps, wLen, &capAimLiveVideo) && MatchShortCapability(caps, wLen, &capAimLiveAudio)) {
- mir_strcpy(szClientBuf, "ICQ 7");
- }
- else if (MatchCapability(caps, wLen, &capFakeHtml)) {
- if (MatchShortCapability(caps, wLen, &capAimLiveVideo) && MatchShortCapability(caps, wLen, &capAimLiveAudio)) {
- mir_strcpy(szClientBuf, "ICQ 6");
- *bClientId = CLID_ICQ6;
- }
- else if (CheckContactCapabilities(hContact, CAPF_RTF) && !CheckContactCapabilities(hContact, CAPF_CONTACTS) && MatchShortCapability(caps, wLen, &capIcqDevils)) {
- mir_strcpy(szClientBuf, "Qnext v4"); // finally handles SRV_RELAY correctly
- *bClientId = CLID_ALTERNATIVE;
- }
- }
- else mir_strcpy(szClientBuf, "icq5.1");
- }
- else mir_strcpy(szClientBuf, "icq5");
-
- if (MatchCapability(caps, wLen, &capRambler))
- mir_strcat(szClientBuf, " (Rambler)");
- else if (MatchCapability(caps, wLen, &capAbv))
- mir_strcat(szClientBuf, " (Abv)");
- else if (MatchCapability(caps, wLen, &capNetvigator))
- mir_strcat(szClientBuf, " (Netvigator)");
-
- szClient = szClientBuf;
- }
- else if (!CheckContactCapabilities(hContact, CAPF_ICQDIRECT)) {
- *bClientId = CLID_ALTERNATIVE;
- if (CheckContactCapabilities(hContact, CAPF_RTF)) {
- // most probably Qnext - try to make that shit at least receiving our msgs
- ClearContactCapabilities(hContact, CAPF_SRV_RELAY);
- debugLogA("Forcing simple messages (QNext client).");
- szClient = "Qnext";
- }
- else if (CheckContactCapabilities(hContact, CAPF_TYPING) && MatchCapability(caps, wLen, &captZers) && MatchCapability(caps, wLen, &capFakeHtml)) {
- if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF) && MatchShortCapability(caps, wLen, &capAimLiveAudio))
- szClient = "Mail.ru Agent (PC)";
- else
- szClient = "Fring";
- }
- else szClient = "pyICQ";
- }
- else szClient = "ICQ Lite v4";
- }
- else if (MatchCapability(caps, wLen, &capIcqLiteNew))
- szClient = "ICQ Lite"; // the new ICQ Lite based on ICQ6
- else if (!CheckContactCapabilities(hContact, CAPF_ICQDIRECT)) {
- if (MatchCapability(caps, wLen, &capFakeHtml) && MatchCapability(caps, wLen, &capOscarChat) && MatchShortCapability(caps, wLen, &capAimSmartCaps))
- szClient = cliTrillian4;
- else if (CheckContactCapabilities(hContact, CAPF_UTF) && !CheckContactCapabilities(hContact, CAPF_RTF))
- szClient = "pyICQ";
- }
- }
- else if (wVersion == 7) {
- if (CheckContactCapabilities(hContact, CAPF_RTF))
- szClient = "GnomeICU"; // this is an exception
- else if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY)) {
- if (!dwFT1 && !dwFT2 && !dwFT3)
- szClient = "&RQ";
- else {
- *bClientId = CLID_GENERIC;
- szClient = "ICQ 2000";
- }
- }
- else if (CheckContactCapabilities(hContact, CAPF_UTF)) {
- if (CheckContactCapabilities(hContact, CAPF_TYPING))
- szClient = "Icq2Go! (Java)";
- else if (wUserClass & CLASS_WIRELESS)
- szClient = "Pocket Web 1&1";
- else
- szClient = "Icq2Go!";
- }
- }
- else if (wVersion == 0xA) {
- if (!CheckContactCapabilities(hContact, CAPF_RTF) && !CheckContactCapabilities(hContact, CAPF_UTF)) {
- // this is bad, but we must do it - try to detect QNext
- ClearContactCapabilities(hContact, CAPF_SRV_RELAY);
- debugLogA("Forcing simple messages (QNext client).");
- szClient = "Qnext";
- }
- else if (!CheckContactCapabilities(hContact, CAPF_RTF) && CheckContactCapabilities(hContact, CAPF_UTF) && !dwFT1 && !dwFT2 && !dwFT3)
- // not really good, but no other option
- szClient = "NanoICQ";
- }
- else if (wVersion == 0xB) {
- if (CheckContactCapabilities(hContact, CAPF_XTRAZ | CAPF_SRV_RELAY | CAPF_TYPING | CAPF_UTF) && MatchShortCapability(caps, wLen, &capIcqDevils))
- szClient = "Mail.ru Agent (Symbian)";
- }
- else if (wVersion == 0) {
- // capability footprint based detection - not really reliable
- if (!dwFT1 && !dwFT2 && !dwFT3 && !dwWebPort && !dwDirectCookie) {
- // DC info is empty
- if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_CONTACTS | CAPF_XTRAZ | CAPF_OSCAR_FILE))
- szClient = "ICQ 8";
- else if (CheckContactCapabilities(hContact, CAPF_TYPING) && MatchCapability(caps, wLen, &capIs2001) &&
- MatchCapability(caps, wLen, &capIs2002) && MatchCapability(caps, wLen, &capComm20012))
- szClient = cliSpamBot;
- else if (MatchShortCapability(caps, wLen, &capAimIcon) && MatchShortCapability(caps, wLen, &capAimDirect) &&
- CheckContactCapabilities(hContact, CAPF_OSCAR_FILE | CAPF_UTF)) { // detect libgaim/libpurple versions
- if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY))
- szClient = "Adium X"; // yeah, AFAIK only Adium has this fixed
- else if (CheckContactCapabilities(hContact, CAPF_TYPING))
- szClient = "libpurple";
- else
- szClient = "libgaim";
- }
- else if (MatchShortCapability(caps, wLen, &capAimIcon) && MatchShortCapability(caps, wLen, &capAimDirect) &&
- MatchCapability(caps, wLen, &capOscarChat) && CheckContactCapabilities(hContact, CAPF_OSCAR_FILE) && wLen == 0x40)
- szClient = "libgaim"; // Gaim 1.5.1 most probably
- else if (CheckContactCapabilities(hContact, CAPF_OSCAR_FILE) && MatchCapability(caps, wLen, &capOscarChat) && wLen == 0x20)
- szClient = "Easy Message";
- else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_TYPING) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchCapability(caps, wLen, &capOscarChat) && wLen == 0x40)
- szClient = "Meebo";
- else if (CheckContactCapabilities(hContact, CAPF_UTF) && MatchShortCapability(caps, wLen, &capAimIcon) && wLen == 0x20)
- szClient = "PyICQ-t Jabber Transport";
- else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_XTRAZ) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchCapability(caps, wLen, &capXtrazVideo))
- szClient = "PyICQ-t Jabber Transport";
- else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_SRV_RELAY | CAPF_ICQDIRECT | CAPF_TYPING) && wLen == 0x40)
- szClient = "Agile Messenger"; // Smartphone 2002
- else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_SRV_RELAY | CAPF_ICQDIRECT | CAPF_OSCAR_FILE) && MatchShortCapability(caps, wLen, &capAimFileShare))
- szClient = "Slick"; // http://lonelycatgames.com/?app=slick
- else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_SRV_RELAY | CAPF_OSCAR_FILE | CAPF_CONTACTS) && MatchShortCapability(caps, wLen, &capAimFileShare) && MatchShortCapability(caps, wLen, &capAimIcon))
- szClient = "Digsby"; // http://www.digsby.com
- else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_SRV_RELAY | CAPF_CONTACTS) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchCapability(caps, wLen, &capFakeHtml))
- szClient = "mundu IM"; // http://messenger.mundu.com
- else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_OSCAR_FILE) && MatchCapability(caps, wLen, &capOscarChat)) {
- if (CheckContactCapabilities(hContact, CAPF_TYPING))
- szClient = "eBuddy"; // http://www.ebuddy.com
- else
- szClient = "eBuddy (Mobile)";
- }
- else if (CheckContactCapabilities(hContact, CAPF_CONTACTS | CAPF_OSCAR_FILE) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchShortCapability(caps, wLen, &capAimDirect) && MatchCapability(caps, wLen, &capOscarChat))
- szClient = "IloveIM"; //http://www.iloveim.com/
-
- }
- }
- }
- }
- else if (!nIsICQ) {
- // detect AIM clients
- if (caps) {
- if (capId = MatchCapability(caps, wLen, &capAimOscar, 8)) {
- // AimOscar Signature
- DWORD aver = (*capId)[0xC] << 0x18 | (*capId)[0xD] << 0x10 | (*capId)[0xE] << 8 | (*capId)[0xF];
- DWORD mver = (*capId)[0x8] << 0x18 | (*capId)[0x9] << 0x10 | (*capId)[0xA] << 8 | (*capId)[0xB];
- szClient = MirandaVersionToStringEx(szClientBuf, 0, "AimOscar", aver, mver);
- bMirandaIM = TRUE;
- }
- else if (capId = MatchCapability(caps, wLen, &capSim, 0xC)) {
- // Sim is universal
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xD];
- unsigned ver3 = (*capId)[0xE];
- szClient = makeClientVersion(szClientBuf, "SIM ", ver1, ver2, ver3, 0);
-
- if ((*capId)[0xF] & 0x80)
- mir_strcat(szClientBuf, "/Win32");
- else if ((*capId)[0xF] & 0x40)
- mir_strcat(szClientBuf, "/MacOS X");
- }
- else if (capId = MatchCapability(caps, wLen, &capKopete, 0xC)) {
- unsigned ver1 = (*capId)[0xC];
- unsigned ver2 = (*capId)[0xD];
- unsigned ver3 = (*capId)[0xE];
- unsigned ver4 = (*capId)[0xF];
- szClient = makeClientVersion(szClientBuf, "Kopete ", ver1, ver2, ver3, ver4);
- }
- else if (MatchCapability(caps, wLen, &capIcqIos) || MatchCapability(caps, wLen, &capIcqAndroid))
- szClient = "ICQ (Mobile)";
- else if (MatchCapability(caps, wLen, &capIm2))
- // IM2 extensions
- szClient = cliIM2;
- else if (MatchCapability(caps, wLen, &capNaim, 0x8))
- szClient = "naim";
- // http://www.dibsby.com
- else if (MatchCapability(caps, wLen, &capDigsby, 0x06) || MatchCapability(caps, wLen, &capDigsbyBeta))
- szClient = "Digsby";
- else if (MatchShortCapability(caps, wLen, &capAimIcon) && MatchCapability(caps, wLen, &capOscarChat) &&
- CheckContactCapabilities(hContact, CAPF_UTF | CAPF_TYPING) && wLen == 0x40)
- szClient = "Meebo";
- // libpurple (e.g. Pidgin 2.7.x)
- else if (wLen == 0x90 && CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_TYPING | CAPF_XTRAZ) &&
- MatchCapability(caps, wLen, &capOscarChat) && MatchShortCapability(caps, wLen, &capAimIcon) &&
- MatchShortCapability(caps, wLen, &capAimDirect) && MatchCapability(caps, wLen, &capFakeHtml))
- szClient = "libpurple";
- // libpurple - Meebo (without DirectIM and OFT)
- else if (wLen == 0x70 && CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_TYPING | CAPF_XTRAZ) &&
- MatchCapability(caps, wLen, &capOscarChat) && MatchShortCapability(caps, wLen, &capAimIcon) &&
- MatchCapability(caps, wLen, &capFakeHtml))
- szClient = "Meebo";
- else
- szClient = "AIM";
- }
- else if (wUserClass & CLASS_WIRELESS)
- szClient = "AIM (Mobile)";
- else {
- DWORD dwUin;
- uid_str szUid;
- getContactUid(hContact, &dwUin, &szUid);
- if (szUid[0]) {
- if (strstr(szUid, "@bk.ru") || strstr(szUid, "@list.ru") || strstr(szUid, "@mail.ru") || strstr(szUid, "@inbox.ru"))
- szClient = "MRA client";
- }
-
- if (szClient == nullptr)
- szClient = "AIM";
- }
- }
-
- // custom miranda packs
- if (caps && bMirandaIM) {
- capId = MatchCapability(caps, wLen, &capMimPack, 4);
- if (capId) {
- char szPack[16];
- mir_snprintf(szPack, " [%.12s]", (*capId) + 4);
-
- // make sure client string is not constant
- if (szClient != szClientBuf) {
- mir_strcpy(szClientBuf, szClient);
- szClient = szClientBuf;
- }
-
- mir_strcat(szClientBuf, szPack);
- }
- }
-
- BOOL bClientDetected = (szClient != nullptr);
-
- // client detection failed, provide default clients
- if (!szClient) {
- *bClientId = CLID_GENERIC;
- switch (wVersion) {
- case 6:
- szClient = "ICQ99";
- break;
- case 7:
- szClient = "ICQ 2000/Icq2Go";
- break;
- case 8:
- szClient = "ICQ 2001-2003a";
- break;
- case 9:
- szClient = "ICQ Lite";
- break;
- case 0xA:
- szClient = "ICQ 2003b";
- }
- }
-
- if (szClient) {
- char *szExtra = nullptr;
-
- if (MatchCapability(caps, wLen, &capSimpLite))
- szExtra = " + SimpLite";
- else if (MatchCapability(caps, wLen, &capSimpPro))
- szExtra = " + SimpPro";
- else if (MatchCapability(caps, wLen, &capIMsecure) || MatchCapability(caps, wLen, &capIMSecKey1, 6) || MatchCapability(caps, wLen, &capIMSecKey2, 6))
- szExtra = " + IMsecure";
-
- if (szExtra) {
- if (szClient != szClientBuf) {
- mir_strcpy(szClientBuf, szClient);
- szClient = szClientBuf;
- }
- mir_strcat(szClientBuf, szExtra);
- }
- }
-
- // Log the detection result if it has changed or contact just logged on...
- if (!szCurrentClient || mir_strcmp(szCurrentClient, szClient)) {
- if (bClientDetected)
- debugLogA("Client identified as %s", szClient);
- else
- debugLogA("No client identification, put default ICQ client for protocol.");
- }
-
- return szClient;
-}
diff --git a/protocols/IcqOscarJ/src/icq_constants.h b/protocols/IcqOscarJ/src/icq_constants.h
deleted file mode 100644
index eb8a1e2533..0000000000
--- a/protocols/IcqOscarJ/src/icq_constants.h
+++ /dev/null
@@ -1,645 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Global constants and default settings are defined here
-// -----------------------------------------------------------------------------
-// Most of the protocol constants follow the naming conventions of the
-// Oscar documentation at http://iserverd.khstu.ru/oscar/index.html
-// BIG THANKS to Alexandr for maintaining this site and to everyone
-// in the ICQ devel community who have helped to collect the data.
-
-#ifndef __ICQ_CONSTANTS_H
-#define __ICQ_CONSTANTS_H
-
-/* Static icon indexes */
-#define ISI_AUTH_REQUEST 0
-#define ISI_AUTH_GRANT 1
-#define ISI_AUTH_REVOKE 2
-#define ISI_ADD_TO_SERVLIST 3
-
-/* Contact menu item indexes */
-#define ICMI_ADD_TO_SERVLIST 0
-#define ICMI_XSTATUS_DETAILS 1
-#define ICMI_OPEN_PROFILE 2
-
-/* Some default settings */
-#define DEFAULT_SERVER_PORT 5190
-#define DEFAULT_SERVER_PORT_SSL 443
-#define DEFAULT_SERVER_HOST "login.icq.com"
-#define DEFAULT_SERVER_HOST_SSL "slogin.icq.com"
-#define DEFAULT_SS_ENABLED 1
-#define DEFAULT_SS_ADDSERVER 1
-#define DEFAULT_SS_LOAD 0
-#define DEFAULT_SS_STORE 1
-#define DEFAULT_SS_GROUP "General"
-
-#define DEFAULT_SECURE_LOGIN 1
-#define DEFAULT_SECURE_CONNECTION 1
-#define DEFAULT_LEGACY_FIX 0
-#define DEFAULT_KEEPALIVE_ENABLED 1
-#define DEFAULT_ANSI_CODEPAGE CP_ACP
-#define DEFAULT_DCMSG_ENABLED 1 // passive dc messaging is default
-#define DEFAULT_TEMPVIS_ENABLED 1 // temporary visible is enabled by default
-#define DEFAULT_MTN_ENABLED 1
-#define DEFAULT_AVATARS_ENABLED 1
-#define DEFAULT_LOAD_AVATARS 1
-#define DEFAULT_BIGGER_AVATARS 0
-#define DEFAULT_AVATARS_CHECK 1
-#define DEFAULT_XSTATUS_ENABLED 1
-#define DEFAULT_XSTATUS_AUTO 1
-#define DEFAULT_XSTATUS_RESET 0
-#define DEFAULT_MOODS_ENABLED 1
-#define DEFAULT_KILLSPAM_ENABLED 1
-
-#define DEFAULT_SLOWSEND 1
-
-#define DEFAULT_POPUPS_ENABLED 1
-#define DEFAULT_SPAM_POPUPS_ENABLED 1
-#define DEFAULT_LOG_POPUPS_ENABLED 1
-#define DEFAULT_POPUPS_SYS_ICONS 1
-#define DEFAULT_LOG0_TEXT_COLORS RGB(0,0,0) // LOG_NOTE
-#define DEFAULT_LOG0_BACK_COLORS RGB(255,255,255)
-#define DEFAULT_LOG0_TIMEOUT 0
-#define DEFAULT_LOG1_TEXT_COLORS RGB(0,0,0) // LOG_WARNING
-#define DEFAULT_LOG1_BACK_COLORS RGB(255,255,255)
-#define DEFAULT_LOG1_TIMEOUT 0
-#define DEFAULT_LOG2_TEXT_COLORS RGB(0,0,0) // LOG_ERROR
-#define DEFAULT_LOG2_BACK_COLORS RGB(255,255,255)
-#define DEFAULT_LOG2_TIMEOUT 0
-#define DEFAULT_LOG3_TEXT_COLORS RGB(0,0,0) // LOG_FATAL
-#define DEFAULT_LOG3_BACK_COLORS RGB(255,255,255)
-#define DEFAULT_LOG3_TIMEOUT 0
-#define DEFAULT_SPAM_TEXT_COLORS RGB(193,0,38)
-#define DEFAULT_SPAM_BACK_COLORS RGB(213,209,208)
-#define DEFAULT_SPAM_TIMEOUT 0
-#define DEFAULT_POPUPS_WIN_COLORS 0
-#define DEFAULT_POPUPS_DEF_COLORS (BYTE)!DEFAULT_POPUPS_WIN_COLORS
-
-/* Database setting names */
-#define DBSETTING_CAPABILITIES "caps"
-// Contact's server-list items
-#define DBSETTING_SERVLIST_ID "ServerId"
-#define DBSETTING_SERVLIST_GROUP "SrvGroupId"
-#define DBSETTING_SERVLIST_PERMIT "SrvPermitId"
-#define DBSETTING_SERVLIST_DENY "SrvDenyId"
-#define DBSETTING_SERVLIST_IGNORE "SrvIgnoreId"
-// Owner's server-list items
-#define DBSETTING_SERVLIST_PRIVACY "SrvVisibilityID"
-#define DBSETTING_SERVLIST_PHOTO "SrvPhotoID"
-#define DBSETTING_SERVLIST_AVATAR "SrvAvatarID"
-#define DBSETTING_SERVLIST_METAINFO "SrvMetaInfoID"
-#define DBSETTING_SERVLIST_UNHANDLED "SrvUnhandledIDList"
-// Contact's data from server-list
-#define DBSETTING_SERVLIST_DATA "ServerData"
-// User Details
-#define DBSETTING_METAINFO_TOKEN "MetaInfoToken"
-#define DBSETTING_METAINFO_TIME "MetaInfoTime"
-#define DBSETTING_METAINFO_SAVED "InfoTS"
-// Status Note & Mood
-#define DBSETTING_STATUS_NOTE "StatusNote"
-#define DBSETTING_STATUS_NOTE_TIME "StatusNoteTS"
-#define DBSETTING_STATUS_MOOD "StatusMood"
-// Custom Status
-#define DBSETTING_XSTATUS_ID "XStatusId"
-#define DBSETTING_XSTATUS_NAME "XStatusName"
-#define DBSETTING_XSTATUS_MSG "XStatusMsg"
-
-
-// Status FLAGS (used to determine status of other users)
-#define ICQ_STATUSF_ONLINE 0x0000
-#define ICQ_STATUSF_AWAY 0x0001
-#define ICQ_STATUSF_DND 0x0002
-#define ICQ_STATUSF_NA 0x0004
-#define ICQ_STATUSF_OCCUPIED 0x0010
-#define ICQ_STATUSF_FFC 0x0020
-#define ICQ_STATUSF_INVISIBLE 0x0100
-
-// Status values (used to set own status)
-#define ICQ_STATUS_ONLINE 0x0000
-#define ICQ_STATUS_AWAY 0x0001
-#define ICQ_STATUS_NA 0x0005
-#define ICQ_STATUS_OCCUPIED 0x0011
-#define ICQ_STATUS_DND 0x0013
-#define ICQ_STATUS_FFC 0x0020
-#define ICQ_STATUS_INVISIBLE 0x0100
-
-#define STATUS_WEBAWARE 0x0001 // Status webaware flag
-#define STATUS_SHOWIP 0x0002 // Status show ip flag
-#define STATUS_BIRTHDAY 0x0008 // User birthday flag
-#define STATUS_WEBFRONT 0x0020 // User active webfront flag
-#define STATUS_DCDISABLED 0x0100 // Direct connection not supported
-#define STATUS_DCAUTH 0x1000 // Direct connection upon authorization
-#define STATUS_DCCONT 0x2000 // DC only with contact users
-
-
-
-// Typing notification statuses
-#define MTN_FINISHED 0x0000
-#define MTN_TYPED 0x0001
-#define MTN_BEGUN 0x0002
-#define MTN_WINDOW_CLOSED 0x000F
-
-
-
-// Ascii Capability IDs
-#define CAP_RTFMSGS "{97B12751-243C-4334-AD22-D6ABF73F1492}"
-#define CAP_UTF8MSGS "{0946134E-4C7F-11D1-8222-444553540000}"
-
-// Binary Capability Sizes
-#define BINARY_CAP_SIZE 16
-#define BINARY_SHORT_CAP_SIZE 2
-
-// Binary Capability IDs
-#define CAP_SRV_RELAY 0x09, 0x46, 0x13, 0x49, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00
-#define CAP_UTF 0x09, 0x46, 0x13, 0x4e, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00
-#define CAP_RTF 0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x92
-#define CAP_CONTACTS 0x09, 0x46, 0x13, 0x4b, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00
-#define CAP_TYPING 0x56, 0x3f, 0xc8, 0x09, 0x0b, 0x6f, 0x41, 0xbd, 0x9f, 0x79, 0x42, 0x26, 0x09, 0xdf, 0xa2, 0xf3
-#define CAP_ICQDIRECT 0x09, 0x46, 0x13, 0x44, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00
-#define CAP_XTRAZ 0x1A, 0x09, 0x3C, 0x6C, 0xD7, 0xFD, 0x4E, 0xC5, 0x9D, 0x51, 0xA6, 0x47, 0x4E, 0x34, 0xF5, 0xA0
-#define CAP_OSCAR_FILE 0x09, 0x46, 0x13, 0x43, 0x4C, 0x7F, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00
-
-// Miranda IM Capability bitmask
-#define CAPF_SRV_RELAY 0x00000001
-#define CAPF_UTF 0x00000002
-#define CAPF_RTF 0x00000004
-#define CAPF_CONTACTS 0x00000010
-#define CAPF_TYPING 0x00000020
-#define CAPF_ICQDIRECT 0x00000080
-#define CAPF_XTRAZ 0x00000100
-#define CAPF_OSCAR_FILE 0x00000400
-#define CAPF_STATUS_MESSAGES 0x10000000
-#define CAPF_STATUS_MOOD 0x40000000
-#define CAPF_XSTATUS 0x80000000
-
-
-// Message Capability IDs
-#define MCAP_SRV_RELAY_FMT_s 0x09461349, 0x4c7f11d1, 0x82224445, 0x53540000
-#define MCAP_REVERSE_DC_REQ_s 0x09461344, 0x4c7f11d1, 0x82224445, 0x53540000
-#define MCAP_FILE_TRANSFER_s 0x09461343, 0x4c7f11d1, 0x82224445, 0x53540000
-#define MCAP_CONTACTS_s 0x0946134b, 0x4c7f11d1, 0x82224445, 0x53540000
-
-// Plugin Type GUIDs
-#define PSIG_MESSAGE_s 0x00000000, 0x00000000, 0x00000000, 0x00000000
-#define PSIG_INFO_PLUGIN_s 0xa0e93f37, 0x4fe9d311, 0xbcd20004, 0xac96dd96
-#define PSIG_STATUS_PLUGIN_s 0x10cf40d1, 0x4fe9d311, 0xbcd20004, 0xac96dd96
-
-// Plugin Message GUIDs
-#define PMSG_QUERY_INFO_s 0xF002BF71, 0x4371D311, 0x8DD20010, 0x4B06462E
-#define PMSG_QUERY_STATUS_s 0x10180670, 0x5471D311, 0x8DD20010, 0x4B06462E
-
-
-
-// Message types
-#define MTYPE_PLAIN 0x01 // Plain text (simple) message
-#define MTYPE_CHAT 0x02 // Chat request message
-#define MTYPE_FILEREQ 0x03 // File request / file ok message
-#define MTYPE_URL 0x04 // URL message (0xFE formatted)
-#define MTYPE_AUTHREQ 0x06 // Authorization request message (0xFE formatted)
-#define MTYPE_AUTHDENY 0x07 // Authorization denied message (0xFE formatted)
-#define MTYPE_AUTHOK 0x08 // Authorization given message (empty)
-#define MTYPE_SERVER 0x09 // Message from OSCAR server (0xFE formatted)
-#define MTYPE_ADDED 0x0C // "You-were-added" message (0xFE formatted)
-#define MTYPE_WWP 0x0D // Web pager message (0xFE formatted)
-#define MTYPE_EEXPRESS 0x0E // Email express message (0xFE formatted)
-#define MTYPE_CONTACTS 0x13 // Contact list message
-#define MTYPE_PLUGIN 0x1A // Plugin message described by text string
-#define MTYPE_AUTOONLINE 0xE7 // Auto online message (internal only)
-#define MTYPE_AUTOAWAY 0xE8 // Auto away message
-#define MTYPE_AUTOBUSY 0xE9 // Auto occupied message
-#define MTYPE_AUTONA 0xEA // Auto not available message
-#define MTYPE_AUTODND 0xEB // Auto do not disturb message
-#define MTYPE_AUTOFFC 0xEC // Auto free for chat message
-// Internal Message types
-#define MTYPE_UNKNOWN 0x00 // Unknown message
-
-#define MTYPE_GREETINGCARD 0x101 // Greeting Card
-#define MTYPE_REQUESTCONTACTS 0x102 // Request for Contacts
-#define MTYPE_MESSAGE 0x103 // Message+
-#define MTYPE_STATUSMSGEXT 0x104 // StatusMsgExt (2003b)
-#define MTYPE_SMS_MESSAGE 0x110 // SMS message from Mobile
-#define MTYPE_SCRIPT_INVITATION 0x201 // Xtraz Invitation
-#define MTYPE_SCRIPT_DATA 0x202 // Xtraz Message
-#define MTYPE_SCRIPT_NOTIFY 0x208 // Xtraz Response
-#define MTYPE_REVERSE_REQUEST 0x401 // Reverse DC request
-
-// Message Plugin Type GUIDs
-#define MGTYPE_MESSAGE_s 0xBE6B7305, 0x0FC2104F, 0xA6DE4DB1, 0xE3564B0E
-#define MGTYPE_STATUSMSGEXT_s 0x811a18bc, 0x0e6c1847, 0xa5916f18, 0xdcc76f1a
-#define MGTYPE_FILE_s 0xF02D12D9, 0x3091D311, 0x8DD70010, 0x4B06462E
-#define MGTYPE_WEBURL_s 0x371C5872, 0xE987D411, 0xA4C100D0, 0xB759B1D9
-#define MGTYPE_CONTACTS_s 0x2A0E7D46, 0x7676D411, 0xBCE60004, 0xAC961EA6
-#define MGTYPE_GREETING_CARD_s 0x01E53B48, 0x2AE4D111, 0xB6790060, 0x97E1E294
-#define MGTYPE_CHAT_s 0xBFF720B2, 0x378ED411, 0xBD280004, 0xAC96D905
-#define MGTYPE_SMS_MESSAGE_s 0x0e28f600, 0x11e7d311, 0xbcf30004, 0xac969dc2
-#define MGTYPE_XTRAZ_SCRIPT_s 0x3b60b3ef, 0xd82a6c45, 0xa4e09c5a, 0x5e67e865
-
-// Message Plugin Sub-Type IDs
-#define MGTYPE_STANDARD_SEND 0x0000
-#define MGTYPE_CONTACTS_REQUEST 0x0002
-#define MGTYPE_SCRIPT_INVITATION 0x0001
-#define MGTYPE_SCRIPT_DATA 0x0002
-#define MGTYPE_SCRIPT_USER_REMOVE 0x0004
-#define MGTYPE_SCRIPT_NOTIFY 0x0008
-#define MGTYPE_UNDEFINED 0xFFFF
-
-
-
-/* Channels */
-#define ICQ_LOGIN_CHAN 0x01
-#define ICQ_DATA_CHAN 0x02
-#define ICQ_ERROR_CHAN 0x03
-#define ICQ_CLOSE_CHAN 0x04
-#define ICQ_PING_CHAN 0x05
-
-/* Families */
-#define ICQ_SERVICE_FAMILY 0x0001
-#define ICQ_LOCATION_FAMILY 0x0002
-#define ICQ_BUDDY_FAMILY 0x0003
-#define ICQ_MSG_FAMILY 0x0004
-#define ICQ_BOS_FAMILY 0x0009
-#define ICQ_LOOKUP_FAMILY 0x000a
-#define ICQ_STATS_FAMILY 0x000b
-#define ICQ_CHAT_NAVIGATION_FAMILY 0x000d
-#define ICQ_CHAT_FAMILY 0x000e
-#define ICQ_AVATAR_FAMILY 0x0010
-#define ICQ_LISTS_FAMILY 0x0013
-#define ICQ_EXTENSIONS_FAMILY 0x0015
-#define ICQ_AUTHORIZATION_FAMILY 0x0017
-#define ICQ_DIRECTORY_FAMILY 0x0025
-
-/* Subtypes for Service Family 0x0001 */
-#define ICQ_ERROR 0x0001
-#define ICQ_CLIENT_READY 0x0002
-#define ICQ_SERVER_READY 0x0003
-#define ICQ_CLIENT_NEW_SERVICE 0x0004
-#define ICQ_SERVER_REDIRECT_SERVICE 0x0005
-#define ICQ_CLIENT_REQ_RATE_INFO 0x0006
-#define ICQ_SERVER_RATE_INFO 0x0007
-#define ICQ_CLIENT_RATE_ACK 0x0008
-#define ICQ_SERVER_RATE_CHANGE 0x000a
-#define ICQ_SERVER_PAUSE 0x000b
-#define ICQ_CLIENT_PAUSE_ACK 0x000c
-#define ICQ_SERVER_RESUME 0x000d
-#define ICQ_CLIENT_REQINFO 0x000e
-#define ICQ_SERVER_NAME_INFO 0x000f
-#define ICQ_SERVER_EVIL_NOTICE 0x0010
-#define ICQ_CLIENT_SET_IDLE 0x0011
-#define ICQ_SERVER_MIGRATIONREQ 0x0012
-#define ICQ_SERVER_MOTD 0x0013
-#define ICQ_CLIENT_FAMILIES 0x0017
-#define ICQ_SERVER_FAMILIES2 0x0018
-#define ICQ_CLIENT_SET_STATUS 0x001e
-#define ICQ_SERVER_EXTSTATUS 0x0021
-
-/* Subtypes for Location Family 0x0002 */
-#define ICQ_LOCATION_CLI_REQ_RIGHTS 0x0002
-#define ICQ_LOCATION_RIGHTS_REPLY 0x0003
-#define ICQ_LOCATION_SET_USER_INFO 0x0004
-#define ICQ_LOCATION_REQ_USER_INFO 0x0005
-#define ICQ_LOCATION_USR_INFO_REPLY 0x0006
-#define ICQ_LOCATION_QRY_USER_INFO 0x0015
-
-/* Subtypes for Buddy Family 0x0003 */
-#define ICQ_USER_CLI_REQBUDDY 0x0002
-#define ICQ_USER_SRV_REPLYBUDDY 0x0003
-#define ICQ_USER_ADDTOLIST 0x0004 /* deprecated */
-#define ICQ_USER_REMOVEFROMLIST 0x0005 /* deprecated */
-#define ICQ_USER_NOTIFY_REJECTED 0x000a
-#define ICQ_USER_ONLINE 0x000b
-#define ICQ_USER_OFFLINE 0x000c
-#define ICQ_USER_ADDTOTEMPLIST 0x000f
-#define ICQ_USER_REMOVEFROMTEMPLIST 0x0010
-
-/* Subtypes for Message Family 0x0004 */
-#define ICQ_MSG_SRV_ERROR 0x0001
-#define ICQ_MSG_CLI_SETPARAMS 0x0002
-#define ICQ_MSG_CLI_RESETPARAMS 0x0003
-#define ICQ_MSG_CLI_REQICBM 0x0004
-#define ICQ_MSG_SRV_REPLYICBM 0x0005
-#define ICQ_MSG_SRV_SEND 0x0006
-#define ICQ_MSG_SRV_RECV 0x0007
-#define ICQ_MSG_SRV_MISSED_MESSAGE 0x000A
-#define ICQ_MSG_RESPONSE 0x000B
-#define ICQ_MSG_SRV_ACK 0x000C
-#define ICQ_MSG_CLI_REQ_OFFLINE 0x0010
-#define ICQ_MSG_MTN 0x0014
-#define ICQ_MSG_SRV_OFFLINE_REPLY 0x0017
-
-/* Subtypes for Privacy Family 0x0009 */
-#define ICQ_PRIVACY_REQ_RIGHTS 0x0002
-#define ICQ_PRIVACY_RIGHTS_REPLY 0x0003
-#define ICQ_CLI_ADDVISIBLE 0x0005
-#define ICQ_CLI_REMOVEVISIBLE 0x0006
-#define ICQ_CLI_ADDINVISIBLE 0x0007
-#define ICQ_CLI_REMOVEINVISIBLE 0x0008
-#define ICQ_PRIVACY_SERVICE_ERROR 0x0009
-#define ICQ_CLI_ADDTEMPVISIBLE 0x000A
-#define ICQ_CLI_REMOVETEMPVISIBLE 0x000B
-
-/* Subtypes for Lookup Family 0x000a */
-#define ICQ_LOOKUP_REQUEST 0x0002
-#define ICQ_LOOKUP_EMAIL_REPLY 0x0003
-
-/* Subtypes for Stats Family 0x000b */
-#define ICQ_STATS_MINREPORTINTERVAL 0x0002
-
-/* Subtypes for Avatar Family 0x0010 */
-#define ICQ_AVATAR_ERROR 0x0001
-#define ICQ_AVATAR_UPLOAD_REQUEST 0x0002
-#define ICQ_AVATAR_UPLOAD_ACK 0x0003
-#define ICQ_AVATAR_GET_REQUEST 0x0006
-#define ICQ_AVATAR_GET_REPLY 0x0007
-
-/* Subtypes for Server Lists Family 0x0013 */
-#define ICQ_LISTS_ERROR 0x0001
-#define ICQ_LISTS_CLI_REQLISTS 0x0002
-#define ICQ_LISTS_SRV_REPLYLISTS 0x0003
-#define ICQ_LISTS_CLI_REQUEST 0x0004
-#define ICQ_LISTS_CLI_CHECK 0x0005
-#define ICQ_LISTS_LIST 0x0006
-#define ICQ_LISTS_GOTLIST 0x0007
-#define ICQ_LISTS_ADDTOLIST 0x0008
-#define ICQ_LISTS_UPDATEGROUP 0x0009
-#define ICQ_LISTS_REMOVEFROMLIST 0x000A
-#define ICQ_LISTS_ACK 0x000E
-#define ICQ_LISTS_UPTODATE 0x000F
-#define ICQ_LISTS_CLI_MODIFYSTART 0x0011
-#define ICQ_LISTS_CLI_MODIFYEND 0x0012
-#define ICQ_LISTS_GRANTAUTH 0x0014
-#define ICQ_LISTS_AUTHGRANTED 0x0015
-#define ICQ_LISTS_REVOKEAUTH 0x0016
-#define ICQ_LISTS_REQUESTAUTH 0x0018
-#define ICQ_LISTS_AUTHREQUEST 0x0019
-#define ICQ_LISTS_CLI_AUTHRESPONSE 0x001A
-#define ICQ_LISTS_SRV_AUTHRESPONSE 0x001B
-#define ICQ_LISTS_YOUWEREADDED 0x001C
-
-/* Subtypes for ICQ Extensions Family 0x0015 */
-#define ICQ_META_ERROR 0x0001
-#define ICQ_META_CLI_REQUEST 0x0002
-#define ICQ_META_SRV_REPLY 0x0003
-#define ICQ_META_SRV_UPDATE 0x0004
-
-/* Subtypes for Authorization Family 0x0017 */
-#define ICQ_SIGNON_ERROR 0x0001
-#define ICQ_SIGNON_LOGIN_REQUEST 0x0002
-#define ICQ_SIGNON_LOGIN_REPLY 0x0003
-#define ICQ_SIGNON_REGISTRATION_REQ 0x0004
-#define ICQ_SIGNON_NEW_UIN 0x0005
-#define ICQ_SIGNON_AUTH_REQUEST 0x0006
-#define ICQ_SIGNON_AUTH_KEY 0x0007
-#define ICQ_SIGNON_REQUEST_IMAGE 0x000C
-#define ICQ_SIGNON_REG_AUTH_IMAGE 0x000D
-
-// Class constants
-#define CLASS_UNCONFIRMED 0x0001
-#define CLASS_ADMINISTRATOR 0x0002
-#define CLASS_AOL 0x0004
-#define CLASS_COMMERCIAL 0x0008
-#define CLASS_FREE 0x0010
-#define CLASS_AWAY 0x0020
-#define CLASS_ICQ 0x0040
-#define CLASS_WIRELESS 0x0080
-#define CLASS_FORWARDING 0x0200
-#define CLASS_BOT 0x0400
-
-// Reply types for SNAC 15/02 & 15/03
-#define CLI_DELETE_OFFLINE_MSGS_REQ 0x003E
-#define CLI_META_INFO_REQ 0x07D0
-#define SRV_META_INFO_REPLY 0x07DA
-
-// Reply subtypes for SNAC 15/02 & 15/03
-#define META_PROCESSING_ERROR 0x0001 // Meta processing error server reply
-#define META_SMS_DELIVERY_RECEIPT 0x0096 // Server SMS response (delivery receipt)
-#define META_SET_PASSWORD_ACK 0x00AA // Set user password server ack
-#define META_UNREGISTER_ACK 0x00B4 // Unregister account server ack
-#define META_BASIC_USERINFO 0x00C8 // User basic info reply
-#define META_WORK_USERINFO 0x00D2 // User work info reply
-#define META_MORE_USERINFO 0x00DC // User more info reply
-#define META_NOTES_USERINFO 0x00E6 // User notes (about) info reply
-#define META_EMAIL_USERINFO 0x00EB // User extended email info reply
-#define META_INTERESTS_USERINFO 0x00F0 // User interests info reply
-#define META_AFFILATIONS_USERINFO 0x00FA // User past/affilations info reply
-#define META_SHORT_USERINFO 0x0104 // Short user information reply
-#define META_HPAGECAT_USERINFO 0x010E // User homepage category information reply
-#define SRV_USER_FOUND 0x01A4 // Search: user found reply
-#define SRV_LAST_USER_FOUND 0x01AE // Search: last user found reply
-#define META_REGISTRATION_STATS_ACK 0x0302 // Registration stats ack
-#define SRV_RANDOM_FOUND 0x0366 // Random search server reply
-#define META_SET_PASSWORD_REQ 0x042E // Set user password request
-#define META_REQUEST_FULL_INFO 0x04B2 // Request full user info
-#define META_REQUEST_SHORT_INFO 0x04BA // Request short user info
-#define META_REQUEST_SELF_INFO 0x04D0 // Request full self user info
-#define META_SEARCH_GENERIC 0x055F // Search user by details (TLV)
-#define META_SEARCH_UIN 0x0569 // Search user by UIN (TLV)
-#define META_SEARCH_EMAIL 0x0573 // Search user by E-mail (TLV)
-#define META_DIRECTORY_QUERY 0x0FA0
-#define META_DIRECTORY_DATA 0x0FAA
-#define META_DIRECTORY_RESPONSE 0x0FB4
-#define META_DIRECTORY_UPDATE 0x0FD2
-#define META_DIRECTORY_UPDATE_ACK 0x0FDC
-
-#define META_XML_INFO 0x08A2 // Server variable requested via xml
-#define META_SET_FULLINFO_REQ 0x0C3A // Set full user info request
-#define META_SET_FULLINFO_ACK 0x0C3F // Server ack for set fullinfo command
-#define META_SPAM_REPORT_ACK 0x2012 // Server ack for user spam report
-
-// Subtypes for Directory meta requests (family 0x5b9)
-#define DIRECTORY_QUERY_INFO 0x0002
-#define DIRECTORY_SET_INFO 0x0003
-#define DIRECTORY_QUERY_MULTI_INFO 0x0006
-#define DIRECTORY_QUERY_INFO_ACK 0x0009
-#define DIRECTORY_SET_INFO_ACK 0x000A
-
-// TLV types
-
-// SECURITY flags
-#define TLV_AUTH 0x02F8 // uint8 User authorization permissions
-#define TLV_WEBAWARE 0x030C // uint8 User 'show web status' permissions
-
-
-// SEARCH only TLVs
-#define TLV_AGERANGE 0x0168 // acombo Age range to search
-#define TLV_KEYWORDS 0x0226 // sstring Whitepages search keywords string
-#define TLV_ONLINEONLY 0x0230 // uint8 Search only online users flag
-#define TLV_UIN 0x0136 // uint32 User uin
-
-// common
-#define TLV_FIRSTNAME 0x0140 // sstring User firstname
-#define TLV_LASTNAME 0x014A // sstring User lastname
-#define TLV_NICKNAME 0x0154 // sstring User nickname
-#define TLV_EMAIL 0x015E // ecombo User email
-#define TLV_GENDER 0x017C // uint8 User gender
-#define TLV_MARITAL 0x033E // uint8 User marital status
-#define TLV_LANGUAGE 0x0186 // uint16 User spoken language
-#define TLV_CITY 0x0190 // sstring User home city name
-#define TLV_STATE 0x019A // sstring User home state abbr
-#define TLV_COUNTRY 0x01A4 // uint16 User home country code
-#define TLV_COMPANY 0x01AE // sstring User work company name
-#define TLV_DEPARTMENT 0x01B8 // sstring User work department name
-#define TLV_POSITION 0x01C2 // sstring User work position (title)
-#define TLV_OCUPATION 0x01CC // uint16 User work ocupation code
-#define TLV_PASTINFO 0x01D6 // icombo User affilations node
-#define TLV_AFFILATIONS 0x01FE // icombo User past info node
-#define TLV_INTERESTS 0x01EA // icombo User interests node
-#define TLV_HOMEPAGE 0x0212 // sstring User homepage category/keywords
-
-// changeinfo
-#define TLV_AGE 0x0172 // uint16 User age
-#define TLV_URL 0x0213 // sstring User homepage url
-#define TLV_BIRTH 0x023A // bcombo User birthday info (year, month, day)
-#define TLV_ABOUT 0x0258 // sstring User notes (about) text
-#define TLV_STREET 0x0262 // sstring User home street address
-#define TLV_ZIPCODE 0x026D // sstring User home zip code
-#define TLV_PHONE 0x0276 // sstring User home phone number
-#define TLV_FAX 0x0280 // sstring User home fax number
-#define TLV_MOBILE 0x028A // sstring User home cellular phone number
-#define TLV_WORKSTREET 0x0294 // sstring User work street address
-#define TLV_WORKCITY 0x029E // sstring User work city name
-#define TLV_WORKSTATE 0x02A8 // sstring User work state name
-#define TLV_WORKCOUNTRY 0x02B2 // uint16 User work country code
-#define TLV_WORKZIPCODE 0x02BD // sstring User work zip code
-#define TLV_WORKPHONE 0x02C6 // sstring User work phone number
-#define TLV_WORKFAX 0x02D0 // sstring User work fax number
-#define TLV_WORKURL 0x02DA // sstring User work webpage url
-#define TLV_TIMEZONE 0x0316 // uint8 User GMT offset
-#define TLV_ORGCITY 0x0320 // sstring User originally from city
-#define TLV_ORGSTATE 0x032A // sstring User originally from state
-#define TLV_ORGCOUNTRY 0x0334 // uint16 User originally from country (code)
-#define TLV_ALLOWSPAM 0x0348 // uint8
-#define TLV_CODEPAGE 0x0352 // uint16 Codepage used for details
-
-
-/* Direct packet types */
-#define PEER_INIT 0xFF
-#define PEER_INIT_ACK 0x01
-#define PEER_MSG_INIT 0x03
-#define PEER_MSG 0x02
-#define PEER_FILE_INIT 0x00
-#define PEER_FILE_INIT_ACK 0x01
-#define PEER_FILE_NEXTFILE 0x02
-#define PEER_FILE_RESUME 0x03
-#define PEER_FILE_STOP 0x04
-#define PEER_FILE_SPEED 0x05
-#define PEER_FILE_DATA 0x06
-
-/* Direct command types */
-#define DIRECT_CANCEL 0x07D0 /* 2000 TCP cancel previous file/chat request */
-#define DIRECT_ACK 0x07DA /* 2010 TCP acknowledge message packet */
-#define DIRECT_MESSAGE 0x07EE /* 2030 TCP message */
-
-// DC types
-#define DC_DISABLED 0x0000 // Direct connection disabled / auth required
-#define DC_HTTPS 0x0001 // Direct connection thru firewall or https proxy
-#define DC_SOCKS 0x0002 // Direct connection thru socks4/5 proxy server
-#define DC_NORMAL 0x0004 // Normal direct connection (without proxy/firewall)
-#define DC_WEB 0x0006 // Web client - no direct connection
-
-// Message flags
-#define MFLAG_NORMAL 0x01 // Normal message
-#define MFLAG_AUTO 0x03 // Auto-message flag
-#define MFLAG_MULTI 0x80 // This is multiple recipients message
-
-// Some SSI constants
-#define SSI_ITEM_BUDDY 0x0000 // Buddy record (name: uin for ICQ and screenname for AIM)
-#define SSI_ITEM_GROUP 0x0001 // Group record
-#define SSI_ITEM_PERMIT 0x0002 // Permit record ("Allow" list in AIM, and "Visible" list in ICQ)
-#define SSI_ITEM_DENY 0x0003 // Deny record ("Block" list in AIM, and "Invisible" list in ICQ)
-#define SSI_ITEM_VISIBILITY 0x0004 // Permit/deny settings or/and bitmask of the AIM classes
-#define SSI_ITEM_PRESENCE 0x0005 // Presence info (if others can see your idle status, etc)
-#define SSI_ITEM_CLIENTDATA 0x0009 // Client specific, e.g. ICQ2k shortcut bar items
-#define SSI_ITEM_IGNORE 0x000e // Ignore list record.
-#define SSI_ITEM_LASTUPDATE 0x000f // Item that contain roster update time (name: "LastUpdateDate")
-#define SSI_ITEM_NONICQ 0x0010 // Non-ICQ contact (to send SMS). Name: 1#EXT, 2#EXT, etc
-#define SSI_ITEM_UNKNOWN2 0x0011 // Unknown.
-#define SSI_ITEM_IMPORTTIME 0x0013 // Item that contain roster import time (name: "Import time")
-#define SSI_ITEM_BUDDYICON 0x0014 // Buddy icon info. (names: "1", "8", etc. according ot the icon type)
-#define SSI_ITEM_SAVED 0x0019
-#define SSI_ITEM_PREAUTH 0x001B
-#define SSI_ITEM_METAINFO 0x0020 // Owner Details' token & last update time
-
-#define SSI_TLV_AWAITING_AUTH 0x0066 // Contact not authorized in list
-#define SSI_TLV_NOT_IN_LIST 0x006A // Always empty
-#define SSI_TLV_UNKNOWN 0x006D // WTF ?
-#define SSI_TLV_SUBITEMS 0x00C8 // List of sub-items IDs
-#define SSI_TLV_VISIBILITY 0x00CA
-#define SSI_TLV_SHORTCUT 0x00CD
-#define SSI_TLV_TIMESTAMP 0x00D4 // Import Timestamp
-#define SSI_TLV_AVATARHASH 0x00D5
-#define SSI_TLV_NAME 0x0131 // Custom contact nickname
-#define SSI_TLV_GROUP_OPENNED 0x0134
-#define SSI_TLV_EMAIL 0x0137 // Custom contact email
-#define SSI_TLV_PHONE 0x0138 // Custom contact phone number
-#define SSI_TLV_PHONE_CELLULAR 0x0139 // Custom contact cellphone number
-#define SSI_TLV_PHONE_SMS 0x013A // Custom contact SMS number
-#define SSI_TLV_COMMENT 0x013C // User comment
-#define SSI_TLV_METAINFO_TOKEN 0x015C // Privacy token for Contact's details
-#define SSI_TLV_METAINFO_TIME 0x015D // Contact's details last update time
-
-#define MAX_SSI_TLV_NAME_SIZE 0x40
-#define MAX_SSI_TLV_COMMENT_SIZE 0x50
-
-// Client ID constants (internal)
-#define CLID_GENERIC 0x00 // Generic clients (eg. older official clients)
-#define CLID_ALTERNATIVE 0x01 // Clients not using tick for MsgID (most third-party clients)
-#define CLID_MIRANDA 0x02 // Hey, that's mate!
-#define CLID_ICQ6 0x10 // Mark ICQ6 as it has some non obvious limitations!
-
-
-// Internal Constants
-#define ICQ_PROTOCOL_NAME "ICQ"
-#define ICQ_PLUG_VERSION PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM)
-#define ICQ_VERSION 11 // Protocol version
-#define DC_TYPE DC_NORMAL // Used for DC settings
-#define MAX_CONTACTSSEND 15
-#define MAX_MESSAGESNACSIZE 8000
-#define CLIENTRATELIMIT 0
-#define COOKIE_TIMEOUT 3600 // One hour
-#define KEEPALIVE_INTERVAL 57 // Slightly less than a minute
-#define WEBFRONTPORT 0x50
-#define CLIENTFEATURES 0x3
-#define URL_FORGOT_PASSWORD "https://www.icq.com/password/"
-#define URL_REGISTER "https://www.icq.com/register/"
-#define FLAP_MARKER 0x2a
-#define CLIENT_MD5_STRING "AOL Instant Messenger (SM)"
-#define UNIQUEIDSETTING "UIN"
-#define UINMAXLEN 11 // DWORD string max len + 1
-#define PASSWORDMAXLEN 16
-#define OSCAR_PROXY_HOST "ars.icq.com"
-#define OSCAR_PROXY_VERSION 0x044A
-
-#define CLIENT_ID_STRING "ICQ Client" // Client identification, mimic ICQ 6.5
-#define CLIENT_ID_CODE 0x010a
-#define CLIENT_VERSION_MAJOR 0x0014
-#define CLIENT_VERSION_MINOR 0x0034
-#define CLIENT_VERSION_LESSER 0x0000
-#define CLIENT_VERSION_BUILD 0x0c18
-#define CLIENT_DISTRIBUTION 0x00000611
-#define CLIENT_LANGUAGE "en"
-#define CLIENT_COUNTRY "us"
-
-#endif /* __ICQ_CONSTANTS_H */
diff --git a/protocols/IcqOscarJ/src/icq_db.cpp b/protocols/IcqOscarJ/src/icq_db.cpp
deleted file mode 100644
index 4026cb3acf..0000000000
--- a/protocols/IcqOscarJ/src/icq_db.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Internal Database API
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-int CIcqProto::getSetting(MCONTACT hContact, const char *szSetting, DBVARIANT *dbv)
-{
- return db_get_s(hContact, m_szModuleName, szSetting, dbv, 0);
-}
-
-double CIcqProto::getSettingDouble(MCONTACT hContact, const char *szSetting, double dDef)
-{
- DBVARIANT dbv = { DBVT_DELETED };
- double dRes;
-
- if (getSetting(hContact, szSetting, &dbv))
- return dDef; // not found, give default
-
- if (dbv.type != DBVT_BLOB || dbv.cpbVal != sizeof(double))
- dRes = dDef;
- else
- dRes = *(double*)dbv.pbVal;
-
- db_free(&dbv);
- return dRes;
-}
-
-DWORD CIcqProto::getContactUin(MCONTACT hContact)
-{
- return getDword(hContact, UNIQUEIDSETTING, 0);
-}
-
-int CIcqProto::getContactUid(MCONTACT hContact, DWORD *pdwUin, uid_str *ppszUid)
-{
- DBVARIANT dbv = { DBVT_DELETED };
- int iRes = 1;
-
- *pdwUin = 0;
- if (ppszUid) *ppszUid[0] = '\0';
-
- if (!getSetting(hContact, UNIQUEIDSETTING, &dbv)) {
- switch (dbv.type) {
- case DBVT_DWORD:
- *pdwUin = dbv.dVal;
- iRes = 0;
- break;
-
- case DBVT_ASCIIZ:
- if (ppszUid) {
- mir_strcpy(*ppszUid, dbv.pszVal);
- iRes = 0;
- }
- else debugLogA("AOL screennames not accepted");
- break;
-
- case DBVT_UTF8:
- if (ppszUid) {
- mir_strcpy(*ppszUid, dbv.pszVal);
- mir_utf8decode(*ppszUid, nullptr);
- iRes = 0;
- }
- else debugLogA("AOL screennames not accepted");
- break;
- }
- db_free(&dbv);
- }
- return iRes;
-}
-
-char* CIcqProto::getSettingStringUtf(MCONTACT hContact, const char *szModule, const char *szSetting, char *szDef)
-{
- DBVARIANT dbv = { DBVT_DELETED };
- if (db_get_utf(hContact, szModule, szSetting, &dbv)) {
- db_free(&dbv); // for a setting with invalid contents/type
- return null_strdup(szDef);
- }
-
- char *szRes = null_strdup(dbv.pszVal);
- db_free(&dbv);
- return szRes;
-}
-
-char* CIcqProto::getSettingStringUtf(MCONTACT hContact, const char *szSetting, char *szDef)
-{
- return getSettingStringUtf(hContact, m_szModuleName, szSetting, szDef);
-}
-
-WORD CIcqProto::getContactStatus(MCONTACT hContact)
-{
- return getWord(hContact, "Status", ID_STATUS_OFFLINE);
-}
-
-int CIcqProto::getSettingStringStatic(MCONTACT hContact, const char *szSetting, char *dest, size_t dest_len)
-{
- if (!db_get_static(hContact, m_szModuleName, szSetting, dest, (int)dest_len))
- return 0;
-
- return db_get_static_utf(hContact, m_szModuleName, szSetting, dest, (int)dest_len);
-}
-
-int CIcqProto::setSettingDouble(MCONTACT hContact, const char *szSetting, double dValue)
-{
- return setSettingBlob(hContact, szSetting, (BYTE*)&dValue, sizeof(double));
-}
-
-int CIcqProto::setSettingBlob(MCONTACT hContact, const char *szSetting, const BYTE *pValue, size_t cbValue)
-{
- return db_set_blob(hContact, m_szModuleName, szSetting, (void*)pValue, (unsigned)cbValue);
-}
-
-int CIcqProto::setContactHidden(MCONTACT hContact, BYTE bHidden)
-{
- int nResult = db_set_b(hContact, "CList", "Hidden", bHidden);
- if (!bHidden) // clear zero setting
- db_unset(hContact, "CList", "Hidden");
-
- return nResult;
-}
-
-void CIcqProto::setStatusMsgVar(MCONTACT hContact, char* szStatusMsg, bool isAnsi)
-{
- if (szStatusMsg && szStatusMsg[0]) {
- if (isAnsi) {
- char *szStatusNote = getSettingStringUtf(hContact, DBSETTING_STATUS_NOTE, "");
- wchar_t *szStatusNoteW = make_unicode_string(szStatusNote);
- int len = (int)mir_wstrlen(szStatusNoteW) * 3 + 1;
- char *szStatusNoteAnsi = (char*)alloca(len);
- WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, szStatusNoteW, -1, szStatusNoteAnsi, len, nullptr, nullptr);
- bool notmatch = false;
- for (int i = 0;; ++i) {
- if (szStatusNoteAnsi[i] != szStatusMsg[i] && szStatusNoteAnsi[i] != '?' && szStatusMsg[i] != '?') {
- notmatch = true;
- break;
- }
- if (!szStatusNoteAnsi[i] || !szStatusMsg[i])
- break;
- }
- szStatusMsg = notmatch ? ansi_to_utf8(szStatusMsg) : szStatusNote;
- SAFE_FREE(&szStatusNoteW);
- if (notmatch)
- SAFE_FREE(&szStatusNote);
- }
-
- char *oldStatusMsg = nullptr;
- DBVARIANT dbv;
- if (!db_get_ws(hContact, "CList", "StatusMsg", &dbv)) {
- oldStatusMsg = make_utf8_string(dbv.pwszVal);
- db_free(&dbv);
- }
-
- if (!oldStatusMsg || mir_strcmp(oldStatusMsg, szStatusMsg))
- db_set_utf(hContact, "CList", "StatusMsg", szStatusMsg);
- SAFE_FREE(&oldStatusMsg);
- if (isAnsi) SAFE_FREE(&szStatusMsg);
- }
- else db_unset(hContact, "CList", "StatusMsg");
-}
-
-int CIcqProto::IsICQContact(MCONTACT hContact)
-{
- char* szProto = GetContactProto(hContact);
-
- return !mir_strcmp(szProto, m_szModuleName);
-}
-
-MEVENT CIcqProto::AddEvent(MCONTACT hContact, WORD wType, DWORD dwTime, DWORD flags, size_t cbBlob, PBYTE pBlob)
-{
- DBEVENTINFO dbei = {};
- dbei.szModule = m_szModuleName;
- dbei.timestamp = dwTime;
- dbei.flags = flags;
- dbei.eventType = wType;
- dbei.cbBlob = (DWORD)cbBlob;
- dbei.pBlob = pBlob;
- return db_event_add(hContact, &dbei);
-}
-
-char* CIcqProto::getContactCListGroup(MCONTACT hContact)
-{
- return getSettingStringUtf(hContact, "CList", "Group", nullptr);
-}
diff --git a/protocols/IcqOscarJ/src/icq_direct.cpp b/protocols/IcqOscarJ/src/icq_direct.cpp
deleted file mode 100644
index 00d3fc61d4..0000000000
--- a/protocols/IcqOscarJ/src/icq_direct.cpp
+++ /dev/null
@@ -1,946 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-struct directthreadstartinfo
-{
- int type; // Only valid for outgoing connections
- int incoming; // 1=incoming, 0=outgoing
- HNETLIBCONN hConnection; // only valid for incoming connections, handle to the connection
- MCONTACT hContact; // Only valid for outgoing connections
- void* pvExtra; // Only valid for outgoing connections
-};
-
-static char client_check_data[] = {
- "As part of this software beta version Mirabilis is "
- "granting a limited access to the ICQ network, "
- "servers, directories, listings, information and databases (\""
- "ICQ Services and Information\"). The "
- "ICQ Service and Information may databases (\""
- "ICQ Services and Information\"). The "
- "ICQ Service and Information may\0"
-};
-
-void CIcqProto::CloseContactDirectConns(MCONTACT hContact)
-{
- mir_cslock l(directConnListMutex);
-
- for (auto &it : directConns) {
- if (!hContact || it->hContact == hContact) {
- HNETLIBCONN hConnection = it->hConnection;
-
- it->hConnection = nullptr; // do not allow reuse
- NetLib_CloseConnection(&hConnection, FALSE);
- }
- }
-}
-
-
-directconnect* CIcqProto::FindFileTransferDC(filetransfer* ft)
-{
- mir_cslock l(directConnListMutex);
-
- for (auto &it : directConns)
- if (it->ft == ft)
- return it;
-
- return nullptr;
-}
-
-
-filetransfer* CIcqProto::FindExpectedFileRecv(DWORD dwUin, DWORD dwTotalSize)
-{
- mir_cslock l(expectedFileRecvMutex);
-
- for (auto &it : expectedFileRecvs)
- if (it->dwUin == dwUin && it->dwTotalSize == dwTotalSize)
- return expectedFileRecvs.removeItem(&it);
-
- return nullptr;
-}
-
-
-int CIcqProto::sendDirectPacket(directconnect* dc, icq_packet* pkt)
-{
- int nResult = Netlib_Send(dc->hConnection, (const char*)pkt->pData, pkt->wLen + 2, 0);
- if (nResult == SOCKET_ERROR) {
- NetLog_Direct("Direct %p socket error: %d, closing", dc->hConnection, GetLastError());
- CloseDirectConnection(dc);
- }
-
- SAFE_FREE((void**)&pkt->pData);
-
- return nResult;
-}
-
-directthreadstartinfo* CreateDTSI(MCONTACT hContact, HNETLIBCONN hConnection, int type)
-{
- directthreadstartinfo *dtsi = (directthreadstartinfo*)SAFE_MALLOC(sizeof(directthreadstartinfo));
- dtsi->hContact = hContact;
- dtsi->hConnection = hConnection;
- if (type == -1)
- dtsi->incoming = 1;
- else
- dtsi->type = type;
-
- return dtsi;
-}
-
-// Check if we have an open and initialized DC with type
-// 'type' to the specified contact
-BOOL CIcqProto::IsDirectConnectionOpen(MCONTACT hContact, int type, int bPassive)
-{
- BOOL bIsOpen = FALSE, bIsCreated = FALSE;
- {
- mir_cslock l(directConnListMutex);
-
- for (auto &it : directConns) {
- if (it && it->type == type) {
- if (it->hContact == hContact) {
- if (it->initialised) {
- // Connection is OK
- bIsOpen = TRUE;
- // we are going to use the conn, so prevent timeout
- it->packetPending = 1;
- break;
- }
- else bIsCreated = TRUE; // we found pending connection
- }
- }
- }
- }
-
- if (!bPassive && !bIsCreated && !bIsOpen && type == DIRECTCONN_STANDARD && m_bDCMsgEnabled == 2) { // do not try to open DC to offline contact
- if (getContactStatus(hContact) == ID_STATUS_OFFLINE) return FALSE;
- // do not try to open DC if previous attempt was not successfull
- if (getByte(hContact, "DCStatus", 0)) return FALSE;
-
- // Set DC status as tried
- setByte(hContact, "DCStatus", 1);
- // Create a new connection
- OpenDirectConnection(hContact, DIRECTCONN_STANDARD, nullptr);
- }
-
- return bIsOpen;
-}
-
-// This function is called from the Netlib when someone is connecting to
-// one of our incomming DC ports
-void icq_newConnectionReceived(HNETLIBCONN hNewConnection, DWORD, void *pExtra)
-{
- // Start a new thread for the incomming connection
- CIcqProto* ppro = (CIcqProto*)pExtra;
- ppro->ForkThread((CIcqProto::MyThreadFunc)&CIcqProto::icq_directThread, CreateDTSI(NULL, hNewConnection, -1));
-}
-
-// Opens direct connection of specified type to specified contact
-void CIcqProto::OpenDirectConnection(MCONTACT hContact, int type, void* pvExtra)
-{
- // Create a new connection
- directthreadstartinfo* dtsi = CreateDTSI(hContact, nullptr, type);
- dtsi->pvExtra = pvExtra;
- ForkThread((MyThreadFunc)&CIcqProto::icq_directThread, dtsi);
-}
-
-// Safely close NetLib connection - do not corrupt direct connection list
-void CIcqProto::CloseDirectConnection(directconnect *dc)
-{
- mir_cslock l(directConnListMutex);
-
- NetLib_CloseConnection(&dc->hConnection, FALSE);
-
- if (dc->hConnection)
- NetLog_Direct("Direct conn closed (%p)", dc->hConnection);
-}
-
-// Called from icq_newConnectionReceived when a new incomming dc is done
-// Called from OpenDirectConnection when a new outgoing dc is done
-// Called from SendDirectMessage when a new outgoing dc is done
-
-void __cdecl CIcqProto::icq_directThread(directthreadstartinfo *dtsi)
-{
- Thread_SetName("ICQ: directThread");
-
- NETLIBPACKETRECVER packetRecv = {};
- directconnect dc = { 0 };
- BOOL bFirstPacket = TRUE;
- size_t nSkipPacketBytes = 0;
- DWORD dwReqMsgID1 = 0, dwReqMsgID2 = 0;
-
- srand(time(0));
- {
- // add to DC connection list
- mir_cslock l(directConnListMutex);
- directConns.insert(&dc);
- }
-
- // Initialize DC struct
- dc.hContact = dtsi->hContact;
- dc.dwThreadId = GetCurrentThreadId();
- dc.incoming = dtsi->incoming;
- dc.hConnection = dtsi->hConnection;
- dc.ft = nullptr;
-
- if (!dc.incoming) {
- dc.type = dtsi->type;
- dc.dwRemoteExternalIP = getDword(dtsi->hContact, "IP", 0);
- dc.dwRemoteInternalIP = getDword(dtsi->hContact, "RealIP", 0);
- dc.dwRemotePort = getWord(dtsi->hContact, "UserPort", 0);
- dc.dwRemoteUin = getContactUin(dtsi->hContact);
- dc.dwConnectionCookie = getDword(dtsi->hContact, "DirectCookie", 0);
- dc.wVersion = getWord(dtsi->hContact, "Version", 0);
-
- if (!dc.dwRemoteExternalIP && !dc.dwRemoteInternalIP) { // we do not have any ip, do not try to connect
- SAFE_FREE((void**)&dtsi);
- goto LBL_Exit;
- }
- if (!dc.dwRemotePort) { // we do not have port, do not try to connect
- SAFE_FREE((void**)&dtsi);
- goto LBL_Exit;
- }
-
- if (dc.type == DIRECTCONN_STANDARD) {
- // do nothing - some specific init for msg sessions
- }
- else if (dc.type == DIRECTCONN_FILE) {
- dc.ft = (filetransfer*)dtsi->pvExtra;
- dc.dwRemotePort = dc.ft->dwRemotePort;
- }
- else if (dc.type == DIRECTCONN_REVERSE) {
- cookie_reverse_connect *pCookie = (cookie_reverse_connect*)dtsi->pvExtra;
-
- dwReqMsgID1 = pCookie->dwMsgID1;
- dwReqMsgID2 = pCookie->dwMsgID2;
- dc.dwReqId = (UINT_PTR)pCookie->ft;
- SAFE_FREE((void**)&pCookie);
- }
- }
- else dc.type = DIRECTCONN_STANDARD;
-
- SAFE_FREE((void**)&dtsi);
-
- // Load local IP information
- dc.dwLocalExternalIP = getDword("IP", 0);
- dc.dwLocalInternalIP = getDword("RealIP", 0);
-
- // Create outgoing DC
- if (!dc.incoming) {
- NETLIBOPENCONNECTION nloc = { 0 };
- IN_ADDR addr = { 0 }, addr2 = { 0 };
-
- if (dc.dwRemoteExternalIP == dc.dwLocalExternalIP && dc.dwRemoteInternalIP)
- addr.S_un.S_addr = htonl(dc.dwRemoteInternalIP);
- else {
- addr.S_un.S_addr = htonl(dc.dwRemoteExternalIP);
- // for different internal, try it also (for LANs with multiple external IP, VPNs, etc.)
- if (dc.dwRemoteInternalIP != dc.dwRemoteExternalIP)
- addr2.S_un.S_addr = htonl(dc.dwRemoteInternalIP);
- }
-
- // IP to connect to is empty, go away
- if (!addr.S_un.S_addr)
- goto LBL_Exit;
-
- nloc.szHost = inet_ntoa(addr);
- nloc.wPort = (WORD)dc.dwRemotePort;
- nloc.timeout = 8; // 8 secs to connect
- dc.hConnection = NetLib_OpenConnection(m_hDirectNetlibUser, dc.type == DIRECTCONN_REVERSE ? "Reverse " : nullptr, &nloc);
- if (!dc.hConnection && addr2.S_un.S_addr) { // first address failed, try second one if available
- nloc.szHost = inet_ntoa(addr2);
- dc.hConnection = NetLib_OpenConnection(m_hDirectNetlibUser, dc.type == DIRECTCONN_REVERSE ? "Reverse " : nullptr, &nloc);
- }
- if (!dc.hConnection) {
- if (CheckContactCapabilities(dc.hContact, CAPF_ICQDIRECT)) { // only if the contact support ICQ DC connections
- if (dc.type != DIRECTCONN_REVERSE) { // try reverse connect
- cookie_reverse_connect *pCookie = (cookie_reverse_connect*)SAFE_MALLOC(sizeof(cookie_reverse_connect));
- DWORD dwCookie;
-
- NetLog_Direct("connect() failed (%d), trying reverse.", GetLastError());
-
- if (pCookie) { // init cookie
- InitMessageCookie(pCookie);
- pCookie->bMessageType = MTYPE_REVERSE_REQUEST;
- pCookie->hContact = dc.hContact;
- pCookie->dwUin = dc.dwRemoteUin;
- pCookie->type = dc.type;
- pCookie->ft = dc.ft;
- dwCookie = AllocateCookie(CKT_REVERSEDIRECT, 0, dc.hContact, pCookie);
- icq_sendReverseReq(&dc, dwCookie, (cookie_message_data*)pCookie);
- goto LBL_Exit;
- }
-
- NetLog_Direct("Reverse failed (%s)", "malloc failed");
- }
- }
- else // Set DC status to failed
- setByte(dc.hContact, "DCStatus", 2);
-
- if (dc.type == DIRECTCONN_REVERSE) // failed reverse connection
- icq_sendReverseFailed(&dc, dwReqMsgID1, dwReqMsgID2, dc.dwReqId);
-
- NetLog_Direct("connect() failed (%d)", GetLastError());
- if (dc.type == DIRECTCONN_FILE) {
- ProtoBroadcastAck(dc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, dc.ft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&dc.ft);
- }
- goto LBL_Exit;
- }
-
- if (dc.type == DIRECTCONN_FILE)
- dc.ft->hConnection = dc.hConnection;
-
- if (dc.wVersion > 6)
- sendPeerInit_v78(&dc);
- else {
- NetLog_Direct("Error: Unsupported direct protocol: %d, closing.", dc.wVersion);
- CloseDirectConnection(&dc);
- goto LBL_Exit;
- }
- }
-
- HANDLE hPacketRecver = Netlib_CreatePacketReceiver(dc.hConnection, 8192);
-
- // Packet receiving loop
-
- while (dc.hConnection) {
- packetRecv.dwTimeout = dc.wantIdleTime ? 0 : 600000;
-
- int recvResult = Netlib_GetMorePackets(hPacketRecver, &packetRecv);
- if (recvResult == 0) {
- NetLog_Direct("Clean closure of direct socket (%p)", dc.hConnection);
- break;
- }
-
- if (recvResult == SOCKET_ERROR) {
- if (GetLastError() == ERROR_TIMEOUT) { // TODO: this will not work on some systems
- if (dc.wantIdleTime) {
- switch (dc.type) {
- case DIRECTCONN_FILE:
- handleFileTransferIdle(&dc);
- break;
- }
- }
- else if (dc.packetPending) { // do we expect packet soon?
- NetLog_Direct("Keeping connection, packet pending.");
- }
- else {
- NetLog_Direct("Connection inactive for 10 minutes, closing.");
- break;
- }
- }
- else {
- NetLog_Direct("Abortive closure of direct socket (%p) (%d)", dc.hConnection, GetLastError());
- break;
- }
- }
-
- if (dc.type == DIRECTCONN_CLOSING)
- packetRecv.bytesUsed = packetRecv.bytesAvailable;
- else if (packetRecv.bytesAvailable < (int)nSkipPacketBytes) { // the whole buffer needs to be skipped
- nSkipPacketBytes -= packetRecv.bytesAvailable;
- packetRecv.bytesUsed = packetRecv.bytesAvailable;
- }
- else {
- size_t i;
- for (i = nSkipPacketBytes, nSkipPacketBytes = 0; (int)i + 2 <= packetRecv.bytesAvailable;) {
- size_t wLen = *(WORD*)(packetRecv.buffer + i);
-
- if (bFirstPacket) {
- if (wLen > 64) { // roughly check first packet size
- NetLog_Direct("Error: Overflowed packet, closing connection.");
- CloseDirectConnection(&dc);
- break;
- }
- bFirstPacket = FALSE;
- }
- else if (packetRecv.bytesAvailable >= (int)i + 2 && wLen > 8190) { // check for too big packages
- NetLog_Direct("Error: Package too big: %d bytes, skipping.");
- nSkipPacketBytes = wLen;
- packetRecv.bytesUsed = int(i + 2);
- break;
- }
-
- if (wLen + 2 + i > (size_t)packetRecv.bytesAvailable)
- break;
-
- if (dc.type == DIRECTCONN_STANDARD && wLen && packetRecv.buffer[i + 2] == 2) {
- if (!DecryptDirectPacket(&dc, packetRecv.buffer + i + 3, wLen - 1)) {
- NetLog_Direct("Error: Corrupted packet encryption, ignoring packet");
- i += wLen + 2;
- continue;
- }
- }
-
- if (dc.type == DIRECTCONN_FILE && dc.initialised)
- handleFileTransferPacket(&dc, packetRecv.buffer + i + 2, wLen);
- else
- handleDirectPacket(&dc, packetRecv.buffer + i + 2, wLen);
-
- i += wLen + 2;
- }
- packetRecv.bytesUsed = (int)i;
- }
- }
-
- // End of packet receiving loop
- NetLib_SafeCloseHandle(&hPacketRecver);
- CloseDirectConnection(&dc);
-
- if (dc.ft) {
- if (dc.ft->fileId != -1) {
- _close(dc.ft->fileId);
- ProtoBroadcastAck(dc.ft->hContact, ACKTYPE_FILE, dc.ft->dwBytesDone == dc.ft->dwTotalSize ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, dc.ft, 0);
- }
- else if (dc.ft->hConnection)
- ProtoBroadcastAck(dc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, dc.ft, 0);
-
- SafeReleaseFileTransfer((basic_filetransfer**)&dc.ft);
- _chdir("\\"); /* so we don't leave a subdir handle open so it can't be deleted */
- }
-
-LBL_Exit:
- // remove from DC connection list
- mir_cslock l(directConnListMutex);
- directConns.remove(&dc);
-}
-
-void CIcqProto::handleDirectPacket(directconnect* dc, PBYTE buf, size_t wLen)
-{
- if (wLen < 1)
- return;
-
- switch (buf[0]) {
- case PEER_FILE_INIT: // first packet of a file transfer
- NetLog_Direct("Received PEER_FILE_INIT from %u", dc->dwRemoteUin);
-
- if (dc->handshake)
- handleFileTransferPacket(dc, buf, wLen);
- else
- NetLog_Direct("Received %s on uninitialised DC, ignoring.", "PEER_FILE_INIT");
-
- break;
-
- case PEER_INIT_ACK: // This is sent as a response to our PEER_INIT packet
- if (wLen != 4) {
- NetLog_Direct("Error: Received malformed PEER_INITACK from %u", dc->dwRemoteUin);
- break;
- }
-
- NetLog_Direct("Received PEER_INITACK from %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing");
-
- if (dc->incoming) dc->handshake = 1;
-
- if (dc->incoming && dc->type == DIRECTCONN_REVERSE) {
- dc->incoming = 0;
-
- cookie_reverse_connect *pCookie;
- if (FindCookie(dc->dwReqId, nullptr, (void**)&pCookie) && pCookie) { // valid reverse DC, check and init session
- FreeCookie(dc->dwReqId);
- if (pCookie->dwUin == dc->dwRemoteUin) { // valid connection
- dc->type = pCookie->type;
- dc->ft = (filetransfer*)pCookie->ft;
- dc->hContact = pCookie->hContact;
- if (dc->type == DIRECTCONN_STANDARD) { // init message session
- sendPeerMsgInit(dc, 0);
- }
- else if (dc->type == DIRECTCONN_FILE) { // init file session
- sendPeerFileInit(dc);
- dc->initialised = 1;
- }
- SAFE_FREE((void**)&pCookie);
- break;
- }
- else {
- SAFE_FREE((void**)&pCookie);
- NetLog_Direct("Error: Invalid connection (UINs does not match).");
- CloseDirectConnection(dc);
- return;
- }
- }
- else {
- NetLog_Direct("Error: Received unexpected reverse DC, closing.");
- CloseDirectConnection(dc);
- return;
- }
- }
- break;
-
- case PEER_INIT: /* connect packet */
- NetLog_Direct("Received PEER_INIT");
-
- buf++;
-
- if (wLen < 3)
- return;
-
- unpackLEWord(&buf, &dc->wVersion);
-
- if (dc->wVersion > 6) { // we support only versions 7 and up
- DWORD dwUin;
- DWORD dwPort;
- DWORD dwCookie;
- MCONTACT hContact = 0;
-
- if (wLen != 0x30) {
- NetLog_Direct("Error: Received malformed PEER_INIT");
- return;
- }
-
- size_t wSecondLen;
- unpackLEWord(&buf, &wSecondLen);
- if (wSecondLen && wSecondLen != 0x2b) { // OMG? GnomeICU sets this to zero
- NetLog_Direct("Error: Received malformed PEER_INIT");
- return;
- }
-
- unpackLEDWord(&buf, &dwUin);
- if (dwUin != m_dwLocalUIN) {
- NetLog_Direct("Error: Received PEER_INIT targeted to %u", dwUin);
- CloseDirectConnection(dc);
- return;
- }
-
- buf += 2; /* 00 00 */
- unpackLEDWord(&buf, &dc->dwRemotePort);
- unpackLEDWord(&buf, &dc->dwRemoteUin);
- unpackDWord(&buf, &dc->dwRemoteExternalIP);
- unpackDWord(&buf, &dc->dwRemoteInternalIP);
- buf++; /* 04: accept direct connections */
- unpackLEDWord(&buf, &dwPort);
- if (dwPort != dc->dwRemotePort) {
- NetLog_Direct("Error: Received malformed PEER_INIT (invalid port)");
- return;
- }
- unpackLEDWord(&buf, &dwCookie);
-
- buf += 8; // Unknown stuff
- unpackLEDWord(&buf, &dc->dwReqId);
-
- if (dc->dwRemoteUin || !dc->dwReqId) { // OMG! Licq sends on reverse connection empty uin
- hContact = HContactFromUIN(dc->dwRemoteUin, nullptr);
- if (hContact == INVALID_CONTACT_ID) {
- NetLog_Direct("Error: Received PEER_INIT from %u not on my list", dwUin);
- CloseDirectConnection(dc);
- return; /* don't allow direct connection with people not on my clist */
- }
-
- if (dc->incoming) { // this is the first PEER_INIT with our cookie
- if (dwCookie != getDword(hContact, "DirectCookie", 0)) {
- NetLog_Direct("Error: Received PEER_INIT with broken cookie");
- CloseDirectConnection(dc);
- return;
- }
- }
- else { // this is the second PEER_INIT with peer cookie
- if (dwCookie != dc->dwConnectionCookie) {
- NetLog_Direct("Error: Received PEER_INIT with broken cookie");
- CloseDirectConnection(dc);
- return;
- }
- }
- }
-
- if (dc->incoming && dc->dwReqId) { // this is reverse connection
- dc->type = DIRECTCONN_REVERSE;
- if (!dc->dwRemoteUin) { // we need to load cookie (licq)
- cookie_reverse_connect *pCookie;
-
- if (FindCookie(dc->dwReqId, nullptr, (void**)&pCookie) && pCookie) { // valid reverse DC, check and init session
- dc->dwRemoteUin = pCookie->dwUin;
- dc->hContact = pCookie->hContact;
- }
- else {
- NetLog_Direct("Error: Received unexpected reverse DC, closing.");
- CloseDirectConnection(dc);
- return;
- }
- }
- }
-
- sendPeerInitAck(dc); // ack good PEER_INIT packet
-
- if (dc->incoming) { // store good IP info
- dc->hContact = hContact;
- dc->dwConnectionCookie = dwCookie;
- setDword(dc->hContact, "IP", dc->dwRemoteExternalIP);
- setDword(dc->hContact, "RealIP", dc->dwRemoteInternalIP);
- sendPeerInit_v78(dc); // reply with our PEER_INIT
- }
- else { // outgoing
- dc->handshake = 1;
-
- if (dc->type == DIRECTCONN_REVERSE) {
- dc->incoming = 1; // this is incoming reverse connection
- dc->type = DIRECTCONN_STANDARD; // we still do not know type
- }
- else if (dc->type == DIRECTCONN_STANDARD) { // send PEER_MSGINIT
- sendPeerMsgInit(dc, 0);
- }
- else if (dc->type == DIRECTCONN_FILE) {
- sendPeerFileInit(dc);
- dc->initialised = 1;
- }
- }
- // Set DC Status to successful
- setByte(dc->hContact, "DCStatus", 0);
- }
- else {
- NetLog_Direct("Unsupported direct protocol: %d, closing connection", dc->wVersion);
- CloseDirectConnection(dc);
- }
- break;
-
- case PEER_MSG: /* messaging packets */
- NetLog_Direct("Received PEER_MSG from %u", dc->dwRemoteUin);
-
- if (dc->initialised)
- handleDirectMessage(dc, buf + 1, wLen - 1);
- else
- NetLog_Direct("Received %s on uninitialised DC, ignoring.", "PEER_MSG");
-
- break;
-
- case PEER_MSG_INIT: /* init message connection */
- // it is sent by both contains GUID of message channel
- if (!m_bDCMsgEnabled) { // DC messaging disabled, close connection
- NetLog_Direct("Messaging DC requested, denied");
- CloseDirectConnection(dc);
- break;
- }
-
- NetLog_Direct("Received PEER_MSG_INIT from %u", dc->dwRemoteUin);
-
- buf++;
- if (wLen != 0x21)
- break;
-
- if (!dc->handshake) {
- NetLog_Direct("Received %s on unitialised DC, ignoring.", "PEER_MSG_INIT");
- break;
- }
- {
- DWORD q1, q2, q3, q4;
-
- buf += 4; /* always 10 */
- buf += 4; /* some id */
- buf += 4; /* sequence - always 0 on incoming */
- unpackDWord(&buf, &q1); // session type GUID
- unpackDWord(&buf, &q2);
- if (!dc->incoming) // skip marker on sequence 1
- buf += 4;
-
- unpackDWord(&buf, &q3);
- unpackDWord(&buf, &q4);
- if (!CompareGUIDs(q1, q2, q3, q4, PSIG_MESSAGE)) { // This is not for normal messages, useless so kill.
- if (CompareGUIDs(q1, q2, q3, q4, PSIG_STATUS_PLUGIN))
- NetLog_Direct("Status Manager Plugin connections not supported, closing.");
- else if (CompareGUIDs(q1, q2, q3, q4, PSIG_INFO_PLUGIN))
- NetLog_Direct("Info Manager Plugin connection not supported, closing.");
- else
- NetLog_Direct("Unknown connection type init, closing.");
-
- CloseDirectConnection(dc);
- break;
- }
- }
-
- if (dc->incoming) // reply with our PEER_MSG_INIT
- sendPeerMsgInit(dc, 1);
-
- NetLog_Direct("Direct message session ready.");
- dc->initialised = 1;
- break;
-
- default:
- NetLog_Direct("Unknown direct packet ignored.");
- break;
- }
-}
-
-void EncryptDirectPacket(directconnect* dc, icq_packet* p)
-{
- unsigned long B1;
- unsigned long M1;
- unsigned long check;
- unsigned int i;
- unsigned char X1;
- unsigned char X2;
- unsigned char X3;
- unsigned char* buf = (unsigned char*)(p->pData + 3);
- unsigned char bak[6];
- unsigned long offset;
- unsigned long key;
- unsigned long hex;
- unsigned long size = p->wLen - 1;
-
- if (dc->wVersion < 4)
- return; // no encryption necessary.
-
- switch (dc->wVersion) {
- case 4:
- case 5:
- offset = 6;
- break;
-
- default:
- offset = 0;
- }
-
- // calculate verification data
- M1 = (rand() % ((size < 255 ? size : 255) - 10)) + 10;
- X1 = buf[M1] ^ 0xFF;
- X2 = rand() % 220;
- X3 = client_check_data[X2] ^ 0xFF;
- if (offset) {
- memcpy(bak, buf, sizeof(bak));
- B1 = (buf[offset + 4] << 24) | (buf[offset + 6] << 16) | (buf[2] << 8) | buf[0];
- }
- else B1 = (buf[4] << 24) | (buf[6] << 16) | (buf[4] << 8) | (buf[6]);
-
- // calculate checkcode
- check = (M1 << 24) | (X1 << 16) | (X2 << 8) | X3;
- check ^= B1;
-
- // main XOR key
- key = 0x67657268 * size + check;
-
- // XORing the actual data
- for (i = 0; i < (size + 3) / 4; i += 4) {
- hex = key + client_check_data[i & 0xFF];
- *(PDWORD)(buf + i) ^= hex;
- }
-
- // in TCPv4 are the first 6 bytes unencrypted
- // so restore them
- if (offset)
- memcpy(buf, bak, sizeof(bak));
-
- // storing the checkcode
- *(PDWORD)(buf + offset) = check;
-}
-
-int DecryptDirectPacket(directconnect* dc, PBYTE buf, size_t wLen)
-{
- unsigned long hex;
- unsigned long B1;
- unsigned long M1;
- unsigned int i;
- unsigned char X1;
- unsigned char X2;
- unsigned char X3;
- unsigned char bak[6];
- unsigned long size = (unsigned long)wLen;
-
- if (dc->wVersion < 4)
- return 1; // no decryption necessary.
-
- if (size < 4)
- return 1;
-
- // backup the first 6 bytes
- unsigned long offset = (dc->wVersion == 4 || dc->wVersion == 5) ? 6 : 0;
- if (offset)
- memcpy(bak, buf, sizeof(bak));
-
- // retrieve checkcode
- unsigned long check = *(PDWORD)(buf + offset);
-
- // main XOR key
- unsigned long key = 0x67657268 * size + check;
-
- for (i = 4; i < (size + 3) / 4; i += 4) {
- hex = key + client_check_data[i & 0xFF];
- *(PDWORD)(buf + i) ^= hex;
- }
-
- // retrive validate data
- if (offset) {
- // in TCPv4 are the first 6 bytes unencrypted
- // so restore them
- memcpy(buf, bak, sizeof(bak));
- B1 = (buf[offset + 4] << 24) | (buf[offset + 6] << 16) | (buf[2] << 8) | buf[0];
- }
- else B1 = (buf[4] << 24) | (buf[6] << 16) | (buf[4] << 8) | (buf[6] << 0);
-
- // special decryption
- B1 ^= check;
-
- // validate packet
- M1 = (B1 >> 24) & 0xFF;
- if (M1 < 10 || M1 >= size)
- return 0;
-
- X1 = buf[M1] ^ 0xFF;
- if (((B1 >> 16) & 0xFF) != X1)
- return 0;
-
- X2 = (BYTE)((B1 >> 8) & 0xFF);
- if (X2 < 220) {
- X3 = client_check_data[X2] ^ 0xFF;
- if ((B1 & 0xFF) != X3)
- return 0;
- }
-
- return 1;
-}
-
-// This should be called only if connection already exists
-int CIcqProto::SendDirectMessage(MCONTACT hContact, icq_packet *pkt)
-{
- mir_cslock l(directConnListMutex);
-
- for (auto &it : directConns) {
- if (it == nullptr)
- continue;
-
- if (it->hContact == hContact) {
- if (it->initialised) {
- // This connection can be reused, send packet and exit
- NetLog_Direct("Sending direct message");
-
- if (pkt->pData[2] == 2)
- EncryptDirectPacket(it, pkt);
-
- sendDirectPacket(it, pkt);
- it->packetPending = 0; // packet done
-
- return TRUE; // Success
- }
- break; // connection not ready, use server instead
- }
- }
-
- return FALSE; // connection pending, we failed, use server instead
-}
-
-// Sends a PEER_INIT packet through a DC
-// -----------------------------------------------------------------------
-// This packet is sent during direct connection initialization between two
-// ICQ clients. It is sent by the originator of the connection to start
-// the handshake and by the receiver directly after it has sent the
-// PEER_ACK packet as a reply to the originator's PEER_INIT. The values
-// after the COOKIE field have been added for v7.
-
-void CIcqProto::sendPeerInit_v78(directconnect* dc)
-{
- icq_packet packet;
- directPacketInit(&packet, 48);
-
- packByte(&packet, PEER_INIT); // Command
- packLEWord(&packet, dc->wVersion); // Version
- packLEWord(&packet, 43); // Data length
- packLEDWord(&packet, dc->dwRemoteUin); // UIN of remote user
- packWord(&packet, 0); // Unknown
- packLEDWord(&packet, wListenPort); // Our port
- packLEDWord(&packet, m_dwLocalUIN); // Our UIN
- packDWord(&packet, dc->dwLocalExternalIP); // Our external IP
- packDWord(&packet, dc->dwLocalInternalIP); // Our internal IP
- packByte(&packet, DC_TYPE); // TCP connection flags
- packLEDWord(&packet, wListenPort); // Our port
- packLEDWord(&packet, dc->dwConnectionCookie); // DC cookie
- packLEDWord(&packet, WEBFRONTPORT); // Unknown
- packLEDWord(&packet, CLIENTFEATURES); // Unknown
- if (dc->type == DIRECTCONN_REVERSE)
- packLEDWord(&packet, dc->dwReqId); // Reverse Request Cookie
- else
- packDWord(&packet, 0); // Unknown
-
- sendDirectPacket(dc, &packet);
-
- NetLog_Direct("Sent PEER_INIT to %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing");
-}
-
-// Sends a PEER_INIT packet through a DC
-// -----------------------------------------------------------------------
-// This is sent to acknowledge a PEER_INIT packet.
-
-void CIcqProto::sendPeerInitAck(directconnect* dc)
-{
- icq_packet packet;
- directPacketInit(&packet, 4); // Packet length
- packLEDWord(&packet, PEER_INIT_ACK); //
-
- sendDirectPacket(dc, &packet);
-
- NetLog_Direct("Sent PEER_INIT_ACK to %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing");
-}
-
-// Sends a PEER_MSG_INIT packet through a DC
-// -----------------------------------------------------------------------
-// This packet starts message session.
-
-void CIcqProto::sendPeerMsgInit(directconnect* dc, DWORD dwSeq)
-{
- icq_packet packet;
- directPacketInit(&packet, 33);
-
- packByte(&packet, PEER_MSG_INIT);
- packLEDWord(&packet, 10); // unknown
- packLEDWord(&packet, 1); // message connection
- packLEDWord(&packet, dwSeq); // sequence is 0,1
- if (!dwSeq) {
- packGUID(&packet, PSIG_MESSAGE); // message type GUID
- packLEWord(&packet, 1); // delimiter
- packLEWord(&packet, 4);
- }
- else {
- packDWord(&packet, 0); // first part of Message GUID
- packDWord(&packet, 0);
- packLEWord(&packet, 1); // delimiter
- packLEWord(&packet, 4);
- packDWord(&packet, 0); // second part of Message GUID
- packDWord(&packet, 0);
- }
- sendDirectPacket(dc, &packet);
-
- NetLog_Direct("Sent PEER_MSG_INIT to %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing");
-}
-
-// Sends a PEER_FILE_INIT packet through a DC
-// -----------------------------------------------------------------------
-// This packet configures file-transfer session.
-
-void CIcqProto::sendPeerFileInit(directconnect* dc)
-{
- ptrA tmp(getStringA("Nick"));
- char *szNick = NEWSTR_ALLOCA((tmp == NULL) ? "" : tmp);
- size_t nNickLen = mir_strlen(szNick);
-
- icq_packet packet;
- directPacketInit(&packet, 20 + nNickLen);
-
- packByte(&packet, PEER_FILE_INIT); /* packet type */
- packLEDWord(&packet, 0); /* unknown */
- packLEDWord(&packet, dc->ft->dwFileCount);
- packLEDWord(&packet, dc->ft->dwTotalSize);
- packLEDWord(&packet, dc->ft->dwTransferSpeed);
- packLEWord(&packet, WORD(nNickLen + 1));
- packBuffer(&packet, (LPBYTE)szNick, nNickLen + 1);
- sendDirectPacket(dc, &packet);
-
- NetLog_Direct("Sent PEER_FILE_INIT to %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing");
-}
diff --git a/protocols/IcqOscarJ/src/icq_direct.h b/protocols/IcqOscarJ/src/icq_direct.h
deleted file mode 100644
index b3780596e9..0000000000
--- a/protocols/IcqOscarJ/src/icq_direct.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#ifndef __ICQ_DIRECT_H
-#define __ICQ_DIRECT_H
-
-struct filetransfer : public basic_filetransfer
-{
- int status;
- int sending;
- int currentIsDir;
- DWORD dwUin;
- DWORD dwRemotePort;
- char *szFilename;
- char *szDescription;
- char *szSavePath;
- char *szThisFile;
- char *szThisSubdir;
- char **pszFiles;
- DWORD dwThisFileSize;
- DWORD dwThisFileDate;
- DWORD dwTotalSize;
- DWORD dwFileCount;
- DWORD dwTransferSpeed;
- DWORD dwBytesDone, dwFileBytesDone;
- int fileId;
- HNETLIBCONN hConnection;
- DWORD dwLastNotify;
- int nVersion; // Was this sent with a v7 or a v8 packet?
- BOOL bDC; // Was this received over a DC or through server?
- BOOL bEmptyDesc; // Was the description empty ?
-};
-
-#define DIRECTCONN_STANDARD 0
-#define DIRECTCONN_FILE 1
-#define DIRECTCONN_CHAT 2
-#define DIRECTCONN_REVERSE 10
-#define DIRECTCONN_CLOSING 15
-
-struct directconnect
-{
- MCONTACT hContact;
- HNETLIBCONN hConnection;
- DWORD dwConnectionCookie;
- int type;
- WORD wVersion;
- int incoming;
- int wantIdleTime;
- int packetPending;
- DWORD dwRemotePort;
- DWORD dwRemoteUin;
- DWORD dwRemoteExternalIP;
- DWORD dwRemoteInternalIP;
- DWORD dwLocalExternalIP;
- DWORD dwLocalInternalIP;
- int initialised;
- int handshake;
- DWORD dwThreadId;
- filetransfer *ft;
- DWORD dwReqId; // Reverse Connect request cookie
-};
-
-int DecryptDirectPacket(directconnect *dc, PBYTE buf, size_t wLen);
-
-#endif /* __ICQ_DIRECT_H */
diff --git a/protocols/IcqOscarJ/src/icq_directmsg.cpp b/protocols/IcqOscarJ/src/icq_directmsg.cpp
deleted file mode 100644
index ca7925b89c..0000000000
--- a/protocols/IcqOscarJ/src/icq_directmsg.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleDirectMessage(directconnect* dc, PBYTE buf, size_t wLen)
-{
- WORD wCommand;
- WORD wCookie;
- BYTE bMsgType, bMsgFlags;
- WORD wStatus;
- WORD wFlags;
- WORD wTextLen;
- char* pszText = nullptr;
-
- // The first part of the packet should always be at least 31 bytes
- if (wLen < 31) {
- NetLog_Direct("Error during parsing of DC packet 2 PEER_MSG (too short)");
- return;
- }
-
- // Skip packet checksum
- buf += 4;
- wLen -= 4;
-
- // Command:
- // 0x07d0 = 2000 - cancel given message.
- // 0x07da = 2010 - acknowledge message.
- // 0x07ee = 2030 - normal message/request.
- unpackLEWord(&buf, &wCommand);
- wLen -= 2;
-
- // Unknown, always 0xe (14)
- buf += 2;
- wLen -= 2;
-
- // Sequence number
- unpackLEWord(&buf, &wCookie);
- wLen -= 2;
-
- // Unknown, always zeroes
- buf += 12;
- wLen -= 12;
-
- // Peer message type
- unpackByte(&buf, &bMsgType);
- // Peer message flags
- unpackByte(&buf, &bMsgFlags);
- wLen -= 2;
-
- // The current status of the user, or whether the message was accepted or not.
- // 0x00 - user is online, or message was receipt, or file transfer accepted
- // 0x01 - refused
- // 0x04 - auto-refused, because of away
- // 0x09 - auto-refused, because of occupied
- // 0x0a - auto-refused, because of dnd
- // 0x0e - auto-refused, because of na
- unpackLEWord(&buf, &wStatus);
- wLen -= 2;
-
- // Flags, or priority
- // Seen: 1 - Chat request
- // 0 - File auto accept (type 3)
- // 33 - priority ?
- unpackLEWord(&buf, &wFlags);
- wLen -= 2;
-
- // Messagetext. This is either the status message or the actual message
- // when this is a PEER_MSG_MSG packet
- unpackLEWord(&buf, &wTextLen);
- if (wTextLen > 0) {
- pszText = (char*)_alloca(wTextLen + 1);
- unpackString(&buf, pszText, wTextLen);
- pszText[wTextLen] = '\0';
- }
- wLen = (wLen - 2) - wTextLen;
-
- NetLog_Direct("Handling PEER_MSG '%s', command %u, cookie %u, messagetype %u, messageflags %u, status %u, flags %u", pszText, wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags);
-
- // The remaining actual message is handled either as a status message request,
- // a greeting message, a acknowledge or a normal (text, url, file) message
- if (wCommand == DIRECT_MESSAGE) {
- switch (bMsgType) {
- case MTYPE_FILEREQ: // File inits
- handleFileRequest(buf, dc->dwRemoteUin, wCookie, 0, 0, pszText, 7, TRUE);
- break;
-
- case MTYPE_AUTOAWAY:
- case MTYPE_AUTOBUSY:
- case MTYPE_AUTONA:
- case MTYPE_AUTODND:
- case MTYPE_AUTOFFC:
- {
- char **szMsg = MirandaStatusToAwayMsg(AwayMsgTypeToStatus(bMsgType));
- if (szMsg)
- icq_sendAwayMsgReplyDirect(dc, wCookie, bMsgType, (const char**)szMsg);
- }
- break;
-
- case MTYPE_PLUGIN: // Greeting
- handleDirectGreetingMessage(dc, buf, wLen, wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags);
- break;
-
- default:
- message_ack_params pMsgAck = { 0 };
- uid_str szUID;
-
- buf -= wTextLen;
- wLen += wTextLen;
-
- pMsgAck.bType = MAT_DIRECT;
- pMsgAck.pDC = dc;
- pMsgAck.wCookie = wCookie;
- pMsgAck.msgType = bMsgType;
- pMsgAck.bFlags = bMsgFlags;
- handleMessageTypes(dc->dwRemoteUin, szUID, time(0), 0, 0, wCookie, dc->wVersion, (int)bMsgType, (int)bMsgFlags, 0, (DWORD)wLen, wTextLen, (char*)buf, MTF_DIRECT, &pMsgAck);
- break;
- }
- }
- else if (wCommand == DIRECT_ACK) {
- if (bMsgFlags == 3) {
- // this is status reply
- uid_str szUID;
-
- buf -= wTextLen;
- wLen += wTextLen;
-
- handleMessageTypes(dc->dwRemoteUin, szUID, time(0), 0, 0, wCookie, dc->wVersion, (int)bMsgType, (int)bMsgFlags, 2, (DWORD)wLen, wTextLen, (char*)buf, MTF_DIRECT, nullptr);
- }
- else {
- MCONTACT hCookieContact;
- cookie_message_data *pCookieData = nullptr;
- if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData))
- NetLog_Direct("Received an unexpected direct ack");
- else if (hCookieContact != dc->hContact) {
- NetLog_Direct("Direct Contact does not match Cookie Contact(0x%x != 0x%x)", dc->hContact, hCookieContact);
- ReleaseCookie(wCookie); // This could be a bad idea, but I think it is safe
- }
- else { // the ack is correct
- int ackType = -1;
-
- switch (bMsgType) {
- case MTYPE_PLAIN:
- ackType = ACKTYPE_MESSAGE;
- break;
- case MTYPE_URL:
- ackType = ACKTYPE_URL;
- break;
- case MTYPE_CONTACTS:
- ackType = ACKTYPE_CONTACTS;
- break;
-
- case MTYPE_FILEREQ: // File acks
- handleFileAck(buf, wLen, dc->dwRemoteUin, wCookie, wStatus);
- break;
-
- case MTYPE_PLUGIN: // Greeting
- handleDirectGreetingMessage(dc, buf, wLen, wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags);
- break;
-
- default:
- NetLog_Direct("Skipped packet from direct connection");
- break;
- }
- if (ackType != -1) { // was a good ack to broadcast ?
- ProtoBroadcastAck(dc->hContact, ackType, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0);
- ReleaseCookie(wCookie);
- }
- }
- }
- }
- else if (wCommand == DIRECT_CANCEL)
- NetLog_Direct("Cannot handle abort messages yet... :(");
- else
- NetLog_Direct("Unknown wCommand, packet skipped");
-}
-
-void CIcqProto::handleDirectGreetingMessage(directconnect* dc, PBYTE buf, size_t wLen, WORD wCommand, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, WORD wStatus, WORD wFlags)
-{
- NetLog_Direct("Handling PEER_MSG_GREETING, command %u, cookie %u, messagetype %u, messageflags %u, status %u, flags %u", wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags);
-
- int typeId;
- WORD qt;
- if (!unpackPluginTypeId(&buf, &wLen, &typeId, &qt, TRUE))
- return;
-
- // Length of remaining data
- size_t dwLengthToEnd;
- unpackLEDWord(&buf, &dwLengthToEnd);
- if (dwLengthToEnd < 4 || dwLengthToEnd > wLen) {
- NetLog_Direct("Error: Sanity checking failed (%d) in handleDirectGreetingMessage, datalen %u wLen %u", 2, dwLengthToEnd, wLen);
- return;
- }
-
- // Length of message/reason
- size_t dwDataLength;
- unpackLEDWord(&buf, &dwDataLength);
- wLen -= 4;
- if (dwDataLength > wLen) {
- NetLog_Direct("Error: Sanity checking failed (%d) in handleDirectGreetingMessage, datalen %u wLen %u", 3, dwDataLength, wLen);
- return;
- }
-
- if (typeId == MTYPE_FILEREQ && wCommand == DIRECT_MESSAGE) {
- NetLog_Direct("This is file request");
- char *szMsg = (char*)_alloca(dwDataLength + 1);
- unpackString(&buf, szMsg, dwDataLength);
- szMsg[dwDataLength] = '\0';
- wLen -= dwDataLength;
-
- handleFileRequest(buf, dc->dwRemoteUin, wCookie, 0, 0, szMsg, 8, TRUE);
- }
- else if (typeId == MTYPE_FILEREQ && wCommand == DIRECT_ACK) {
- NetLog_Direct("This is file ack");
- char *szMsg = (char*)_alloca(dwDataLength + 1);
- unpackString(&buf, szMsg, dwDataLength);
- szMsg[dwDataLength] = '\0';
- wLen -= dwDataLength;
-
- // 50 - file request granted/refused
- handleFileAck(buf, wLen, dc->dwRemoteUin, wCookie, wStatus);
- }
- else if (typeId && wCommand == DIRECT_MESSAGE) {
- uid_str szUID;
- message_ack_params pMsgAck = { 0 };
-
- pMsgAck.bType = MAT_DIRECT;
- pMsgAck.pDC = dc;
- pMsgAck.wCookie = wCookie;
- pMsgAck.msgType = typeId;
- handleMessageTypes(dc->dwRemoteUin, szUID, time(0), 0, 0, wCookie, dc->wVersion, typeId, 0, 0, dwLengthToEnd, dwDataLength, (char*)buf, MTF_PLUGIN | MTF_DIRECT, &pMsgAck);
- }
- else if (typeId == MTYPE_STATUSMSGEXT && wCommand == DIRECT_ACK) { // especially for icq2003b
- NetLog_Direct("This is extended status reply");
-
- char *szMsg = (char*)_alloca(dwDataLength + 1);
- unpackString(&buf, szMsg, dwDataLength);
- szMsg[dwDataLength] = '\0';
-
- uid_str szUID;
- handleMessageTypes(dc->dwRemoteUin, szUID, time(0), 0, 0, wCookie, dc->wVersion, (int)(qt + 0xE7), 3, 2, wLen, dwDataLength, szMsg, MTF_PLUGIN | MTF_DIRECT, nullptr);
- }
- else if (typeId && wCommand == DIRECT_ACK) {
- MCONTACT hCookieContact;
- cookie_message_data *pCookieData = nullptr;
-
- if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData)) {
- NetLog_Direct("Received an unexpected direct ack");
- }
- else if (hCookieContact != dc->hContact) {
- NetLog_Direct("Direct Contact does not match Cookie Contact(0x%x != 0x%x)", dc->hContact, hCookieContact);
- ReleaseCookie(wCookie); // This could be a bad idea, but I think it is safe
- }
- else {
- int ackType = -1;
-
- switch (typeId) {
- case MTYPE_MESSAGE:
- ackType = ACKTYPE_MESSAGE;
- break;
- case MTYPE_URL:
- ackType = ACKTYPE_URL;
- break;
- case MTYPE_CONTACTS:
- ackType = ACKTYPE_CONTACTS;
- break;
- case MTYPE_SCRIPT_NOTIFY:
- {
- char *szMsg = (char*)_alloca(dwDataLength + 1);
- if (dwDataLength > 0)
- memcpy(szMsg, buf, dwDataLength);
- szMsg[dwDataLength] = '\0';
-
- handleXtrazNotifyResponse(dc->hContact, wCookie, szMsg);
- }
- break;
-
- default:
- NetLog_Direct("Skipped packet from direct connection");
- break;
- }
-
- if (ackType != -1) { // was a good ack to broadcast ?
- ProtoBroadcastAck(dc->hContact, ackType, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0);
- }
- // Release cookie
- ReleaseCookie(wCookie);
- }
- }
- else NetLog_Direct("Unsupported plugin message type %s", typeId);
-}
diff --git a/protocols/IcqOscarJ/src/icq_fieldnames.cpp b/protocols/IcqOscarJ/src/icq_fieldnames.cpp
deleted file mode 100644
index db2ab4bf28..0000000000
--- a/protocols/IcqOscarJ/src/icq_fieldnames.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-FieldNamesItem timezonesField[] =
-{
- { -100, nullptr }
-};
-
-const FieldNamesItem countryField[] = {
- { 9999, LPGEN("Other") },
- { 93, LPGEN("Afghanistan") },
- { 355, LPGEN("Albania") },
- { 213, LPGEN("Algeria") },
- { 376, LPGEN("Andorra") },
- { 244, LPGEN("Angola") },
- { 1264, LPGEN("Anguilla") },
- { 1268, LPGEN("Antigua and Barbuda") },
- { 54, LPGEN("Argentina") },
- { 374, LPGEN("Armenia") },
- { 297, LPGEN("Aruba") },
- { 247, LPGEN("Ascension Island") },
- { 61, LPGEN("Australia") },
- { 6720, LPGEN("Australia, Antarctic Territory") }, /* added country code 672(0)*/
- { 614, LPGEN("Australia, Christmas Island") }, /* rename (from Christmas Island) and change to official county code 61(4) (from 672) */
- { 61891, LPGEN("Australia, Cocos (Keeling) Islands") }, /* rename and change to official county code 61(891) (from 6102) */
- { 6723, LPGEN("Australia, Norfolk Island") }, /* rename (from Norfolk Island) and change to official county code 672(3) (from 6722) */
- { 43, LPGEN("Austria") },
- { 994, LPGEN("Azerbaijan") },
- { 1242, LPGEN("Bahamas") },
- { 973, LPGEN("Bahrain") },
- { 880, LPGEN("Bangladesh") },
- { 1246, LPGEN("Barbados") },
- //{120, LPGEN("Barbuda")}, /* removed: it is not a country and no special island, see Antigua and Barbuda*/
- { 375, LPGEN("Belarus") },
- { 32, LPGEN("Belgium") },
- { 501, LPGEN("Belize") },
- { 229, LPGEN("Benin") },
- { 1441, LPGEN("Bermuda") },
- { 975, LPGEN("Bhutan") },
- { 591, LPGEN("Bolivia") },
- { 387, LPGEN("Bosnia and Herzegovina") },
- { 267, LPGEN("Botswana") },
- { 55, LPGEN("Brazil") },
- { 106, LPGEN("British Virgin Islands") },
- { 673, LPGEN("Brunei") },
- { 359, LPGEN("Bulgaria") },
- { 226, LPGEN("Burkina Faso") },
- { 257, LPGEN("Burundi") },
- { 855, LPGEN("Cambodia") },
- { 237, LPGEN("Cameroon") },
- { 1002, LPGEN("Canada") },
- { 178, LPGEN("Canary Islands") },
- { 238, LPGEN("Cape Verde") },
- { 1345, LPGEN("Cayman Islands") },
- { 236, LPGEN("Central African Republic") },
- { 235, LPGEN("Chad") },
- { 56, LPGEN("Chile") },
- { 86, LPGEN("China") },
- { 57, LPGEN("Colombia") },
- { 269, LPGEN("Comoros") },
- { 243, LPGEN("Congo, Democratic Republic of the") },
- { 242, LPGEN("Congo, Republic of the") },
- { 682, LPGEN("Cook Islands") },
- { 506, LPGEN("Costa Rica") },
- { 225, LPGEN("Cote d'Ivoire") },
- { 385, LPGEN("Croatia") },
- { 53, LPGEN("Cuba") },
- { 357, LPGEN("Greek, Republic of South Cyprus") }, /* rename coz Turkey, Republic of Northern Cyprus */
- { 420, LPGEN("Czech Republic") },
- { 45, LPGEN("Denmark") },
- { 246, LPGEN("Diego Garcia") },
- { 253, LPGEN("Djibouti") },
- { 1767, LPGEN("Dominica") },
- { 1809, LPGEN("Dominican Republic") },
- { 593, LPGEN("Ecuador") },
- { 20, LPGEN("Egypt") },
- { 503, LPGEN("El Salvador") },
- { 240, LPGEN("Equatorial Guinea") },
- { 291, LPGEN("Eritrea") },
- { 372, LPGEN("Estonia") },
- { 251, LPGEN("Ethiopia") },
- { 3883, LPGEN("Europe") }, /* add county code +388 3 official European Telephony Numbering Space*/
- { 298, LPGEN("Faroe Islands") },
- { 500, LPGEN("Falkland Islands") },
- { 679, LPGEN("Fiji") },
- { 358, LPGEN("Finland") },
- { 33, LPGEN("France") },
- { 5901, LPGEN("French Antilles") },
- { 594, LPGEN("French Guiana") },
- { 689, LPGEN("French Polynesia") },
- { 241, LPGEN("Gabon") },
- { 220, LPGEN("Gambia") },
- { 995, LPGEN("Georgia") },
- { 49, LPGEN("Germany") },
- { 233, LPGEN("Ghana") },
- { 350, LPGEN("Gibraltar") },
- { 30, LPGEN("Greece") },
- { 299, LPGEN("Greenland") },
- { 1473, LPGEN("Grenada") },
- { 590, LPGEN("Guadeloupe") },
- { 1671, LPGEN("Guam, US Territory of") },
- { 502, LPGEN("Guatemala") },
- { 224, LPGEN("Guinea") },
- { 245, LPGEN("Guinea-Bissau") },
- { 592, LPGEN("Guyana") },
- { 509, LPGEN("Haiti") },
- { 504, LPGEN("Honduras") },
- { 852, LPGEN("Hong Kong") },
- { 36, LPGEN("Hungary") },
- { 354, LPGEN("Iceland") },
- { 91, LPGEN("India") },
- { 62, LPGEN("Indonesia") },
- { 98, LPGEN("Iran") },
- { 964, LPGEN("Iraq") },
- { 353, LPGEN("Ireland") },
- { 972, LPGEN("Israel") },
- { 39, LPGEN("Italy") },
- { 1876, LPGEN("Jamaica") },
- { 81, LPGEN("Japan") },
- { 962, LPGEN("Jordan") },
- { 705, LPGEN("Kazakhstan") },
- { 254, LPGEN("Kenya") },
- { 686, LPGEN("Kiribati") },
- { 850, LPGEN("Korea, North") },
- { 82, LPGEN("Korea, South") },
- { 965, LPGEN("Kuwait") },
- { 996, LPGEN("Kyrgyzstan") },
- { 856, LPGEN("Laos") },
- { 371, LPGEN("Latvia") },
- { 961, LPGEN("Lebanon") },
- { 266, LPGEN("Lesotho") },
- { 231, LPGEN("Liberia") },
- { 218, LPGEN("Libya") },
- { 423, LPGEN("Liechtenstein") },
- { 370, LPGEN("Lithuania") },
- { 352, LPGEN("Luxembourg") },
- { 853, LPGEN("Macau") },
- { 389, LPGEN("Macedonia, Republic of") },
- { 261, LPGEN("Madagascar") },
- { 265, LPGEN("Malawi") },
- { 60, LPGEN("Malaysia") },
- { 960, LPGEN("Maldives") },
- { 223, LPGEN("Mali") },
- { 356, LPGEN("Malta") },
- { 692, LPGEN("Marshall Islands") },
- { 596, LPGEN("Martinique") },
- { 222, LPGEN("Mauritania") },
- { 230, LPGEN("Mauritius") },
- { 262, LPGEN("Mayotte") },
- { 52, LPGEN("Mexico") },
- { 691, LPGEN("Micronesia, Federated States of") },
- { 373, LPGEN("Moldova") },
- { 377, LPGEN("Monaco") },
- { 976, LPGEN("Mongolia") },
- { 1664, LPGEN("Montserrat") },
- { 212, LPGEN("Morocco") },
- { 258, LPGEN("Mozambique") },
- { 95, LPGEN("Myanmar") },
- { 264, LPGEN("Namibia") },
- { 674, LPGEN("Nauru") },
- { 977, LPGEN("Nepal") },
- { 31, LPGEN("Netherlands") },
- { 599, LPGEN("Netherlands Antilles") }, /* dissolved 2010 */
- { 5995, LPGEN("St. Maarten") }, /* add new country in 2010 (from Netherlands Antilles) */
- { 5999, LPGEN("Curacao") }, /* add new country in 2010 (from Netherlands Antilles) */
- { 5997, LPGEN("Netherlands (Bonaire Island)") }, /* add new Part of Netherlands in 2010 (from Netherlands Antilles) */
- { 59946, LPGEN("Netherlands (Saba Island)") }, /* add new Part of Netherlands in 2010 (from Netherlands Antilles) */
- { 59938, LPGEN("Netherlands (St. Eustatius Island)") }, /* add new Part of Netherlands in 2010 (from Netherlands Antilles) */
- { 687, LPGEN("New Caledonia") },
- { 64, LPGEN("New Zealand") },
- { 505, LPGEN("Nicaragua") },
- { 227, LPGEN("Niger") },
- { 234, LPGEN("Nigeria") },
- { 683, LPGEN("Niue") },
- { 1670, LPGEN("Northern Mariana Islands, US Territory of") }, /* added NANP */
- { 47, LPGEN("Norway") },
- { 968, LPGEN("Oman") },
- { 92, LPGEN("Pakistan") },
- { 680, LPGEN("Palau") },
- { 507, LPGEN("Panama") },
- { 675, LPGEN("Papua New Guinea") },
- { 595, LPGEN("Paraguay") },
- { 51, LPGEN("Peru") },
- { 63, LPGEN("Philippines") },
- { 48, LPGEN("Poland") },
- { 351, LPGEN("Portugal") },
- { 1939, LPGEN("Puerto Rico") },
- { 974, LPGEN("Qatar") },
- { 262, LPGEN("Reunion") },
- { 40, LPGEN("Romania") },
- { 7, LPGEN("Russia") },
- { 250, LPGEN("Rwanda") },
- { 1684, LPGEN("Samoa (USA)") }, /* rename (from American Samoa) change county code to NANP (from 684) */
- { 685, LPGEN("Samoa, Western") }, /* rename (from Western Samoa) */
- { 290, LPGEN("Saint Helena") },
- { 1869, LPGEN("Saint Kitts and Nevis") },
- { 1758, LPGEN("Saint Lucia") },
- { 508, LPGEN("Saint Pierre and Miquelon") },
- { 1784, LPGEN("Saint Vincent and the Grenadines") },
- { 378, LPGEN("San Marino") },
- { 239, LPGEN("Sao Tome and Principe") },
- { 966, LPGEN("Saudi Arabia") },
- { 442, LPGEN("Scotland") },
- { 221, LPGEN("Senegal") },
- { 248, LPGEN("Seychelles") },
- { 232, LPGEN("Sierra Leone") },
- { 65, LPGEN("Singapore") },
- { 421, LPGEN("Slovakia") },
- { 386, LPGEN("Slovenia") },
- { 677, LPGEN("Solomon Islands") },
- { 252, LPGEN("Somalia") },
- { 27, LPGEN("South Africa") },
- { 34, LPGEN("Spain") },
- { 3492, LPGEN("Spain, Canary Islands") }, /*rename and change county code to 34(92) spain + canary code*/
- { 94, LPGEN("Sri Lanka") },
- { 249, LPGEN("Sudan") },
- { 597, LPGEN("Suriname") },
- { 268, LPGEN("Swaziland") },
- { 46, LPGEN("Sweden") },
- { 41, LPGEN("Switzerland") },
- { 963, LPGEN("Syria") },
- { 886, LPGEN("Taiwan") },
- { 992, LPGEN("Tajikistan") },
- { 255, LPGEN("Tanzania") },
- { 66, LPGEN("Thailand") },
- //{6702, LPGEN("Tinian Island")}, /* removed: it is not a country it is part of Northern Mariana Islands, US Territory of */
- { 670, LPGEN("Timor, East") }, /* added (is part off Northern Mariana Islands but not US Territory*/
- { 228, LPGEN("Togo") },
- { 690, LPGEN("Tokelau") },
- { 676, LPGEN("Tonga") },
- { 1868, LPGEN("Trinidad and Tobago") },
- { 216, LPGEN("Tunisia") },
- { 90, LPGEN("Turkey") },
- { 90392, LPGEN("Turkey, Republic of Northern Cyprus") }, /* added (is diffrent from Greek part)*/
- { 993, LPGEN("Turkmenistan") },
- { 1649, LPGEN("Turks and Caicos Islands") },
- { 688, LPGEN("Tuvalu") },
- { 256, LPGEN("Uganda") },
- { 380, LPGEN("Ukraine") },
- { 971, LPGEN("United Arab Emirates") },
- { 44, LPGEN("United Kingdom") },
- { 598, LPGEN("Uruguay") },
- { 1, LPGEN("USA") },
- { 998, LPGEN("Uzbekistan") },
- { 678, LPGEN("Vanuatu") },
- { 379, LPGEN("Vatican City") },
- { 58, LPGEN("Venezuela") },
- { 84, LPGEN("Vietnam") },
- { 1284, LPGEN("Virgin Islands (UK)") }, /* change county code to NANP (from 105) - rename coz Virgin Islands (USA) */
- { 1340, LPGEN("Virgin Islands (USA)") }, /* change county code to NANP (from 123) */
- { 441, LPGEN("Wales") },
- { 681, LPGEN("Wallis and Futuna") },
- { 967, LPGEN("Yemen") },
- { 38, LPGEN("Yugoslavia") },
- { 381, LPGEN("Serbia") }, /* rename need (from Yugoslavia)*/
- { 383, LPGEN("Kosovo, Republic of") }, /*change country code (from 3811), rename need (from Yugoslavia - Serbia) */
- { 382, LPGEN("Montenegro") }, /* rename need (from Yugoslavia - Montenegro) */
- { 260, LPGEN("Zambia") },
- { 263, LPGEN("Zimbabwe") },
- { 0, nullptr }
-};
-
-const FieldNamesItem interestsField[] =
-{
- { 137, LPGEN("50's") },
- { 134, LPGEN("60's") },
- { 135, LPGEN("70's") },
- { 136, LPGEN("80's") },
- { 100, LPGEN("Art") },
- { 128, LPGEN("Astronomy") },
- { 147, LPGEN("Audio and Visual") },
- { 125, LPGEN("Business") },
- { 146, LPGEN("Business Services") },
- { 101, LPGEN("Cars") },
- { 102, LPGEN("Celebrity Fans") },
- { 130, LPGEN("Clothing") },
- { 103, LPGEN("Collections") },
- { 104, LPGEN("Computers") },
- { 105, LPGEN("Culture") },
- { 122, LPGEN("Ecology") },
- { 139, LPGEN("Entertainment") },
- { 138, LPGEN("Finance and Corporate") },
- { 106, LPGEN("Fitness") },
- { 142, LPGEN("Health and Beauty") },
- { 108, LPGEN("Hobbies") },
- { 150, LPGEN("Home Automation") },
- { 144, LPGEN("Household Products") },
- { 107, LPGEN("Games") },
- { 124, LPGEN("Government") },
- { 109, LPGEN("ICQ - Help") },
- { 110, LPGEN("Internet") },
- { 111, LPGEN("Lifestyle") },
- { 145, LPGEN("Mail Order Catalog") },
- { 143, LPGEN("Media") },
- { 112, LPGEN("Movies and TV") },
- { 113, LPGEN("Music") },
- { 126, LPGEN("Mystics") },
- { 123, LPGEN("News and Media") },
- { 114, LPGEN("Outdoors") },
- { 115, LPGEN("Parenting") },
- { 131, LPGEN("Parties") },
- { 116, LPGEN("Pets and Animals") },
- { 149, LPGEN("Publishing") },
- { 117, LPGEN("Religion") },
- { 141, LPGEN("Retail Stores") },
- { 118, LPGEN("Science") },
- { 119, LPGEN("Skills") },
- { 133, LPGEN("Social science") },
- { 129, LPGEN("Space") },
- { 148, LPGEN("Sporting and Athletic") },
- { 120, LPGEN("Sports") },
- { 127, LPGEN("Travel") },
- { 121, LPGEN("Web Design") },
- { 132, LPGEN("Women") },
- { -1, nullptr }
-};
-
-const FieldNamesItem languageField[] =
-{
- { 55, LPGEN("Afrikaans") },
- { 58, LPGEN("Albanian") },
- { 1, LPGEN("Arabic") },
- { 59, LPGEN("Armenian") },
- { 68, LPGEN("Azerbaijani") },
- { 72, LPGEN("Belorussian") },
- { 2, LPGEN("Bhojpuri") },
- { 56, LPGEN("Bosnian") },
- { 3, LPGEN("Bulgarian") },
- { 4, LPGEN("Burmese") },
- { 5, LPGEN("Cantonese") },
- { 6, LPGEN("Catalan") },
- { 61, LPGEN("Chamorro") },
- { 7, LPGEN("Chinese") },
- { 8, LPGEN("Croatian") },
- { 9, LPGEN("Czech") },
- { 10, LPGEN("Danish") },
- { 11, LPGEN("Dutch") },
- { 12, LPGEN("English") },
- { 13, LPGEN("Esperanto") },
- { 14, LPGEN("Estonian") },
- { 15, LPGEN("Farsi") },
- { 16, LPGEN("Finnish") },
- { 17, LPGEN("French") },
- { 18, LPGEN("Gaelic") },
- { 19, LPGEN("German") },
- { 20, LPGEN("Greek") },
- { 70, LPGEN("Gujarati") },
- { 21, LPGEN("Hebrew") },
- { 22, LPGEN("Hindi") },
- { 23, LPGEN("Hungarian") },
- { 24, LPGEN("Icelandic") },
- { 25, LPGEN("Indonesian") },
- { 26, LPGEN("Italian") },
- { 27, LPGEN("Japanese") },
- { 28, LPGEN("Khmer") },
- { 29, LPGEN("Korean") },
- { 69, LPGEN("Kurdish") },
- { 30, LPGEN("Lao") },
- { 31, LPGEN("Latvian") },
- { 32, LPGEN("Lithuanian") },
- { 65, LPGEN("Macedonian") },
- { 33, LPGEN("Malay") },
- { 63, LPGEN("Mandarin") },
- { 62, LPGEN("Mongolian") },
- { 34, LPGEN("Norwegian") },
- { 57, LPGEN("Persian") },
- { 35, LPGEN("Polish") },
- { 36, LPGEN("Portuguese") },
- { 60, LPGEN("Punjabi") },
- { 37, LPGEN("Romanian") },
- { 38, LPGEN("Russian") },
- { 39, LPGEN("Serbian") },
- { 66, LPGEN("Sindhi") },
- { 40, LPGEN("Slovak") },
- { 41, LPGEN("Slovenian") },
- { 42, LPGEN("Somali") },
- { 43, LPGEN("Spanish") },
- { 44, LPGEN("Swahili") },
- { 45, LPGEN("Swedish") },
- { 46, LPGEN("Tagalog") },
- { 64, LPGEN("Taiwanese") },
- { 71, LPGEN("Tamil") },
- { 47, LPGEN("Tatar") },
- { 48, LPGEN("Thai") },
- { 49, LPGEN("Turkish") },
- { 50, LPGEN("Ukrainian") },
- { 51, LPGEN("Urdu") },
- { 52, LPGEN("Vietnamese") },
- { 67, LPGEN("Welsh") },
- { 53, LPGEN("Yiddish") },
- { 54, LPGEN("Yoruba") },
- { 0, nullptr }
-};
-
-const FieldNamesItem pastField[] =
-{
- { 300, LPGEN("Elementary School") },
- { 301, LPGEN("High School") },
- { 302, LPGEN("College") },
- { 303, LPGEN("University") },
- { 304, LPGEN("Military") },
- { 305, LPGEN("Past Work Place") },
- { 306, LPGEN("Past Organization") },
- { 399, LPGEN("Other") },
- { 0, nullptr }
-};
-
-const FieldNamesItem genderField[] =
-{
- { 'F', LPGEN("Female") },
- { 'M', LPGEN("Male") },
- { 0, nullptr }
-};
-
-const FieldNamesItem studyLevelField[] =
-{
- { 4, LPGEN("Associated degree") },
- { 5, LPGEN("Bachelor's degree") },
- { 1, LPGEN("Elementary") },
- { 2, LPGEN("High-school") },
- { 6, LPGEN("Master's degree") },
- { 7, LPGEN("PhD") },
- { 8, LPGEN("Postdoctoral") },
- { 3, LPGEN("University / College") },
- { 0, nullptr }
-};
-
-const FieldNamesItem industryField[] =
-{
- { 2, LPGEN("Agriculture") },
- { 3, LPGEN("Arts") },
- { 4, LPGEN("Construction") },
- { 5, LPGEN("Consumer Goods") },
- { 6, LPGEN("Corporate Services") },
- { 7, LPGEN("Education") },
- { 8, LPGEN("Finance") },
- { 9, LPGEN("Government") },
- { 10, LPGEN("High Tech") },
- { 11, LPGEN("Legal") },
- { 12, LPGEN("Manufacturing") },
- { 13, LPGEN("Media") },
- { 14, LPGEN("Medical & Health Care") },
- { 15, LPGEN("Non-Profit Organization Management") },
- { 19, LPGEN("Other") },
- { 16, LPGEN("Recreation, Travel & Entertainment") },
- { 17, LPGEN("Service Industry") },
- { 18, LPGEN("Transportation") },
- { 0, nullptr }
-};
-
-const FieldNamesItem occupationField[] =
-{
- { 1, LPGEN("Academic") },
- { 2, LPGEN("Administrative") },
- { 3, LPGEN("Art/Entertainment") },
- { 4, LPGEN("College Student") },
- { 5, LPGEN("Computers") },
- { 6, LPGEN("Community & Social") },
- { 7, LPGEN("Education") },
- { 8, LPGEN("Engineering") },
- { 9, LPGEN("Financial Services") },
- { 10, LPGEN("Government") },
- { 11, LPGEN("High School Student") },
- { 12, LPGEN("Home") },
- { 13, LPGEN("ICQ - Providing Help") },
- { 14, LPGEN("Law") },
- { 15, LPGEN("Managerial") },
- { 16, LPGEN("Manufacturing") },
- { 17, LPGEN("Medical/Health") },
- { 18, LPGEN("Military") },
- { 19, LPGEN("Non-Government Organization") },
- { 20, LPGEN("Professional") },
- { 21, LPGEN("Retail") },
- { 22, LPGEN("Retired") },
- { 23, LPGEN("Science & Research") },
- { 24, LPGEN("Sports") },
- { 25, LPGEN("Technical") },
- { 26, LPGEN("University Student") },
- { 27, LPGEN("Web Building") },
- { 99, LPGEN("Other Services") },
- { 0, nullptr }
-};
-
-const FieldNamesItem affiliationField[] =
-{
- { 200, LPGEN("Alumni Org.") },
- { 201, LPGEN("Charity Org.") },
- { 202, LPGEN("Club/Social Org.") },
- { 203, LPGEN("Community Org.") },
- { 204, LPGEN("Cultural Org.") },
- { 205, LPGEN("Fan Clubs") },
- { 206, LPGEN("Fraternity/Sorority") },
- { 207, LPGEN("Hobbyists Org.") },
- { 208, LPGEN("International Org.") },
- { 209, LPGEN("Nature and Environment Org.") },
- { 210, LPGEN("Professional Org.") },
- { 211, LPGEN("Scientific/Technical Org.") },
- { 212, LPGEN("Self Improvement Group") },
- { 213, LPGEN("Spiritual/Religious Org.") },
- { 214, LPGEN("Sports Org.") },
- { 215, LPGEN("Support Org.") },
- { 216, LPGEN("Trade and Business Org.") },
- { 217, LPGEN("Union") },
- { 218, LPGEN("Volunteer Org.") },
- { 299, LPGEN("Other") },
- { 0, nullptr }
-};
-
-const FieldNamesItem agesField[] =
-{
- { 0x0011000D, LPGEN("13-17") },
- { 0x00160012, LPGEN("18-22") },
- { 0x001D0017, LPGEN("23-29") },
- { 0x0027001E, LPGEN("30-39") },
- { 0x00310028, LPGEN("40-49") },
- { 0x003B0032, LPGEN("50-59") },
- { 0x2710003C, LPGEN("60-above") },
- { -1, nullptr }
-};
-
-const FieldNamesItem maritalField[] =
-{
- { 10, LPGEN("Single") },
- { 11, LPGEN("Close relationships") },
- { 12, LPGEN("Engaged") },
- { 20, LPGEN("Married") },
- { 30, LPGEN("Divorced") },
- { 31, LPGEN("Separated") },
- { 40, LPGEN("Widowed") },
- { 50, LPGEN("Open relationship") },
- { 255, LPGEN("Other") },
- { 0, nullptr }
-};
-
-char* LookupFieldName(const FieldNamesItem *table, int code)
-{
- if (code != 0)
- for (int i = 0; table[i].text; i++)
- if (table[i].code == code)
- return table[i].text;
-
- return nullptr;
-}
-
-char* LookupFieldNameUtf(const FieldNamesItem *table, int code, char *str, size_t strsize)
-{
- char *szText = LookupFieldName(table, code);
- if (szText)
- return ICQTranslateUtfStatic(szText, str, strsize);
-
- return nullptr;
-}
diff --git a/protocols/IcqOscarJ/src/icq_fieldnames.h b/protocols/IcqOscarJ/src/icq_fieldnames.h
deleted file mode 100644
index e7b2fa009b..0000000000
--- a/protocols/IcqOscarJ/src/icq_fieldnames.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#pragma once
-
-struct FieldNamesItem
-{
- int code;
- char *text;
-};
-
-extern FieldNamesItem timezonesField[];
-extern const FieldNamesItem countryField[];
-extern const FieldNamesItem interestsField[];
-extern const FieldNamesItem languageField[];
-extern const FieldNamesItem pastField[];
-extern const FieldNamesItem genderField[];
-extern const FieldNamesItem agesField[];
-extern const FieldNamesItem studyLevelField[];
-extern const FieldNamesItem industryField[];
-extern const FieldNamesItem occupationField[];
-extern const FieldNamesItem affiliationField[];
-extern const FieldNamesItem maritalField[];
-
-char *LookupFieldName(const FieldNamesItem *table, int code);
-char *LookupFieldNameUtf(const FieldNamesItem *table, int code, char *str, size_t strsize);
diff --git a/protocols/IcqOscarJ/src/icq_filerequests.cpp b/protocols/IcqOscarJ/src/icq_filerequests.cpp
deleted file mode 100644
index 793caa9712..0000000000
--- a/protocols/IcqOscarJ/src/icq_filerequests.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleFileAck(PBYTE buf, size_t wLen, DWORD dwUin, DWORD dwCookie, WORD wStatus)
-{
- char* pszFileName = nullptr;
- DWORD dwFileSize;
- MCONTACT hCookieContact;
- WORD wPort;
- filetransfer* ft;
-
- // Find the filetransfer that belongs to this response
- if (!FindCookie(dwCookie, &hCookieContact, (void**)&ft)) {
- NetLog_Direct("Error: Received unexpected file transfer request response");
- return;
- }
-
- FreeCookie(dwCookie);
-
- if (hCookieContact != HContactFromUIN(dwUin, nullptr)) {
- NetLog_Direct("Error: UINs do not match in file transfer request response");
- return;
- }
-
- // If status != 0, a request has been denied
- if (wStatus != 0) {
- NetLog_Direct("File transfer denied by %u.", dwUin);
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)ft, 0);
-
- FreeCookie(dwCookie);
-
- return;
- }
-
- if (wLen < 6) { // sanity check
- NetLog_Direct("Ignoring malformed file transfer request response");
- return;
- }
-
- // Port to connect to
- unpackWord(&buf, &wPort);
- ft->dwRemotePort = wPort;
- wLen -= 2;
-
- // Unknown
- buf += 2;
- wLen -= 2;
-
- // Filename
- size_t wFilenameLength;
- unpackLEWord(&buf, &wFilenameLength);
- if (wFilenameLength > 0) {
- if (wFilenameLength > wLen - 2)
- wFilenameLength = wLen - 2;
- pszFileName = (char*)_alloca(wFilenameLength + 1);
- unpackString(&buf, pszFileName, wFilenameLength);
- pszFileName[wFilenameLength] = '\0';
- }
- wLen -= wFilenameLength + 2;
-
- if (wLen >= 4)
- unpackLEDWord(&buf, &dwFileSize);
- else
- dwFileSize = 0;
-
- NetLog_Direct("File transfer ack from %u, port %u, name %s, size %u", dwUin, ft->dwRemotePort, pszFileName, dwFileSize);
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)ft, 0);
-
- OpenDirectConnection(ft->hContact, DIRECTCONN_FILE, ft);
-}
-
-filetransfer* CIcqProto::CreateFileTransfer(MCONTACT hContact, DWORD dwUin, int nVersion)
-{
- filetransfer *ft = CreateIcqFileTransfer();
-
- ft->dwUin = dwUin;
- ft->hContact = hContact;
- ft->nVersion = nVersion;
- ft->pMessage.bMessageType = MTYPE_FILEREQ;
- InitMessageCookie(&ft->pMessage);
-
- return ft;
-}
-
-// pszDescription points to a string with the reason
-// buf points to the first data after the string
-void CIcqProto::handleFileRequest(PBYTE buf, DWORD dwUin, DWORD dwCookie, DWORD dwID1, DWORD dwID2, char* pszDescription, int nVersion, BOOL bDC)
-{
- BOOL bEmptyDesc = FALSE;
- if (mir_strlen(pszDescription) == 0) {
- pszDescription = Translate("No description given");
- bEmptyDesc = TRUE;
- }
-
- // Empty port+pad
- buf += 4;
-
- // Filename
- size_t wFilenameLength;
- unpackLEWord(&buf, &wFilenameLength);
- if (!wFilenameLength) {
- NetLog_Direct("Ignoring malformed file send request");
- return;
- }
-
- char *pszFileName = (char*)_alloca(wFilenameLength + 1);
- unpackString(&buf, pszFileName, wFilenameLength);
- pszFileName[wFilenameLength] = '\0';
-
- // Total filesize
- DWORD dwFileSize;
- unpackLEDWord(&buf, &dwFileSize);
-
- int bAdded;
- MCONTACT hContact = HContactFromUIN(dwUin, &bAdded);
-
- // Initialize a filetransfer struct
- filetransfer *ft = CreateFileTransfer(hContact, dwUin, nVersion);
- ft->dwCookie = dwCookie;
- ft->szFilename = mir_strdup(pszFileName);
- ft->szDescription = nullptr;
- ft->fileId = -1;
- ft->dwTotalSize = dwFileSize;
- ft->pMessage.dwMsgID1 = dwID1;
- ft->pMessage.dwMsgID2 = dwID2;
- ft->bDC = bDC;
- ft->bEmptyDesc = bEmptyDesc;
-
- // Send chain event
- wchar_t* ptszFileName = mir_utf8decodeW(pszFileName);
-
- PROTORECVFILE pre = { 0 };
- pre.dwFlags = PRFF_UNICODE;
- pre.fileCount = 1;
- pre.timestamp = time(0);
- pre.descr.w = mir_utf8decodeW(pszDescription);
- pre.files.w = &ptszFileName;
- pre.lParam = (LPARAM)ft;
- ProtoChainRecvFile(hContact, &pre);
-
- mir_free(pre.descr.w);
- mir_free(ptszFileName);
-}
-
-void CIcqProto::handleDirectCancel()
-{
- NetLog_Direct("handleDirectCancel: Unhandled cancel");
-}
-
-// *******************************************************************************
-
-void CIcqProto::icq_CancelFileTransfer(filetransfer* ft)
-{
- DWORD dwCookie;
- if (FindCookieByData(ft, &dwCookie, nullptr))
- FreeCookie(dwCookie); /* this bit stops a send that's waiting for acceptance */
-
- if (IsValidFileTransfer(ft)) { // Transfer still out there, end it
- NetLib_CloseConnection(&ft->hConnection, FALSE);
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
-
- if (!FindFileTransferDC(ft)) // Release orphan structure only
- SafeReleaseFileTransfer((basic_filetransfer**)&ft);
- }
-}
diff --git a/protocols/IcqOscarJ/src/icq_filetransfer.cpp b/protocols/IcqOscarJ/src/icq_filetransfer.cpp
deleted file mode 100644
index 9caec02d08..0000000000
--- a/protocols/IcqOscarJ/src/icq_filetransfer.cpp
+++ /dev/null
@@ -1,482 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-static void file_buildProtoFileTransferStatus(filetransfer* ft, PROTOFILETRANSFERSTATUS* pfts)
-{
- memset(pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
- pfts->hContact = ft->hContact;
- pfts->flags = PFTS_UTF | (ft->sending ? PFTS_SENDING : PFTS_RECEIVING); /* Standard FT is Ansi only */
- if (ft->sending)
- pfts->pszFiles.a = ft->pszFiles;
- else
- pfts->pszFiles.a = nullptr; /* FIXME */
- pfts->totalFiles = ft->dwFileCount;
- pfts->currentFileNumber = ft->iCurrentFile;
- pfts->totalBytes = ft->dwTotalSize;
- pfts->totalProgress = ft->dwBytesDone;
- pfts->szWorkingDir.a = ft->szSavePath;
- pfts->szCurrentFile.a = ft->szThisFile;
- pfts->currentFileSize = ft->dwThisFileSize;
- pfts->currentFileTime = ft->dwThisFileDate;
- pfts->currentFileProgress = ft->dwFileBytesDone;
-}
-
-
-static void file_sendTransferSpeed(CIcqProto* ppro, directconnect* dc)
-{
- icq_packet packet;
- directPacketInit(&packet, 5);
- packByte(&packet, PEER_FILE_SPEED); /* Ident */
- packLEDWord(&packet, dc->ft->dwTransferSpeed);
- ppro->sendDirectPacket(dc, &packet);
-}
-
-
-static void file_sendNick(CIcqProto* ppro, directconnect* dc)
-{
- ptrA tmp(ppro->getStringA("Nick"));
- char *szNick = NEWSTR_ALLOCA((tmp == NULL) ? "" : tmp);
- size_t nNickLen = mir_strlen(szNick);
-
- icq_packet packet;
- directPacketInit(&packet, 8 + nNickLen);
- packByte(&packet, PEER_FILE_INIT_ACK); /* Ident */
- packLEDWord(&packet, dc->ft->dwTransferSpeed);
- packLEWord(&packet, WORD(nNickLen + 1));
- packBuffer(&packet, (LPBYTE)szNick, nNickLen + 1);
- ppro->sendDirectPacket(dc, &packet);
-}
-
-
-static void file_sendNextFile(CIcqProto* ppro, directconnect* dc)
-{
- struct _stati64 statbuf;
- char szThisSubDir[MAX_PATH];
-
- if (dc->ft->iCurrentFile >= (int)dc->ft->dwFileCount) {
- ppro->ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dc->ft, 0);
- ppro->CloseDirectConnection(dc);
- dc->ft->hConnection = nullptr;
- return;
- }
-
- dc->ft->szThisFile = dc->ft->pszFiles[dc->ft->iCurrentFile];
- if (FileStatUtf(dc->ft->szThisFile, &statbuf)) {
- ppro->icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it."));
- ppro->CloseDirectConnection(dc);
- dc->ft->hConnection = nullptr;
- return;
- }
-
- char *pszThisFileName = FindFilePathContainer((LPCSTR*)dc->ft->pszFiles, dc->ft->iCurrentFile, szThisSubDir);
-
- if (statbuf.st_mode & _S_IFDIR)
- dc->ft->currentIsDir = 1;
- else {
- dc->ft->currentIsDir = 0;
- dc->ft->fileId = OpenFileUtf(dc->ft->szThisFile, _O_BINARY | _O_RDONLY, _S_IREAD);
- if (dc->ft->fileId == -1) {
- ppro->icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it."));
- ppro->CloseDirectConnection(dc);
- dc->ft->hConnection = nullptr;
- return;
- }
- }
-
- dc->ft->dwThisFileSize = statbuf.st_size;
- dc->ft->dwThisFileDate = statbuf.st_mtime;
- dc->ft->dwFileBytesDone = 0;
-
- char *szThisFileNameAnsi = nullptr, *szThisSubDirAnsi = nullptr;
- if (!utf8_decode(pszThisFileName, &szThisFileNameAnsi))
- szThisFileNameAnsi = _strdup(pszThisFileName); // Legacy fix
- if (!utf8_decode(szThisSubDir, &szThisSubDirAnsi))
- szThisSubDirAnsi = _strdup(szThisSubDir); // Legacy fix
-
- size_t wThisFileNameLen = mir_strlen(szThisFileNameAnsi);
- size_t wThisSubDirLen = mir_strlen(szThisSubDirAnsi);
-
- icq_packet packet;
- directPacketInit(&packet, 20 + wThisFileNameLen + wThisSubDirLen);
- packByte(&packet, PEER_FILE_NEXTFILE); /* Ident */
- packByte(&packet, (BYTE)((statbuf.st_mode & _S_IFDIR) != 0)); // Is subdir
- packLEWord(&packet, WORD(wThisFileNameLen + 1));
- packBuffer(&packet, (LPBYTE)szThisFileNameAnsi, wThisFileNameLen + 1);
- packLEWord(&packet, WORD(wThisSubDirLen + 1));
- packBuffer(&packet, (LPBYTE)szThisSubDirAnsi, wThisSubDirLen + 1);
- packLEDWord(&packet, dc->ft->dwThisFileSize);
- packLEDWord(&packet, statbuf.st_mtime);
- packLEDWord(&packet, dc->ft->dwTransferSpeed);
- SAFE_FREE(&szThisFileNameAnsi);
- SAFE_FREE(&szThisSubDirAnsi);
- ppro->sendDirectPacket(dc, &packet);
-
- ppro->ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, dc->ft, 0);
-}
-
-
-static void file_sendResume(CIcqProto* ppro, directconnect* dc)
-{
- icq_packet packet;
- directPacketInit(&packet, 17);
- packByte(&packet, PEER_FILE_RESUME); /* Ident */
- packLEDWord(&packet, dc->ft->dwFileBytesDone); /* file resume */
- packLEDWord(&packet, 0); /* unknown */
- packLEDWord(&packet, dc->ft->dwTransferSpeed);
- packLEDWord(&packet, dc->ft->iCurrentFile + 1); /* file number */
- ppro->sendDirectPacket(dc, &packet);
-}
-
-
-static void file_sendData(CIcqProto* ppro, directconnect* dc)
-{
- BYTE buf[2048];
- int bytesRead = 0;
-
- if (!dc->ft->currentIsDir) {
- icq_packet packet;
-
- if (dc->ft->fileId == -1)
- return;
- bytesRead = _read(dc->ft->fileId, buf, sizeof(buf));
- if (bytesRead == -1)
- return;
-
- directPacketInit(&packet, 1 + bytesRead);
- packByte(&packet, PEER_FILE_DATA); /* Ident */
- packBuffer(&packet, buf, bytesRead);
- ppro->sendDirectPacket(dc, &packet);
- }
-
- dc->ft->dwBytesDone += bytesRead;
- dc->ft->dwFileBytesDone += bytesRead;
-
- if (GetTickCount() > dc->ft->dwLastNotify + 500 || bytesRead == 0) {
- PROTOFILETRANSFERSTATUS pfts;
-
- file_buildProtoFileTransferStatus(dc->ft, &pfts);
- ppro->ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, dc->ft, (LPARAM)&pfts);
-
- dc->ft->dwLastNotify = GetTickCount();
- }
-
- if (bytesRead == 0) {
- if (!dc->ft->currentIsDir) _close(dc->ft->fileId);
- dc->ft->fileId = -1;
- dc->wantIdleTime = 0;
- dc->ft->iCurrentFile++;
- file_sendNextFile(ppro, dc); /* this will close the socket if no more files */
- }
-}
-
-
-void CIcqProto::handleFileTransferIdle(directconnect* dc)
-{
- file_sendData(this, dc);
-}
-
-
-void CIcqProto::icq_sendFileResume(filetransfer *ft, int action, const char *szFilename)
-{
- if (ft->hConnection == nullptr)
- return;
-
- directconnect *dc = FindFileTransferDC(ft);
- if (!dc)
- return; // something is broken...
-
- int openFlags;
-
- switch (action) {
- case FILERESUME_RESUME:
- openFlags = _O_BINARY | _O_WRONLY;
- break;
-
- case FILERESUME_OVERWRITE:
- openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY;
- ft->dwFileBytesDone = 0;
- break;
-
- case FILERESUME_SKIP:
- openFlags = _O_BINARY | _O_WRONLY;
- ft->dwFileBytesDone = ft->dwThisFileSize;
- break;
-
- case FILERESUME_RENAME:
- openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY;
- SAFE_FREE(&ft->szThisFile);
- ft->szThisFile = null_strdup(szFilename);
- ft->dwFileBytesDone = 0;
- break;
-
- default:
- openFlags = 0;
- }
-
- ft->fileId = OpenFileUtf(ft->szThisFile, openFlags, _S_IREAD | _S_IWRITE);
- if (ft->fileId == -1) {
- icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder."));
- NetLib_CloseConnection(&ft->hConnection, FALSE);
- return;
- }
-
- if (action == FILERESUME_RESUME)
- ft->dwFileBytesDone = _lseek(ft->fileId, 0, SEEK_END);
- else
- _lseek(ft->fileId, ft->dwFileBytesDone, SEEK_SET);
-
- ft->dwBytesDone += ft->dwFileBytesDone;
-
- file_sendResume(this, dc);
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
-}
-
-
-// small utility function
-void NormalizeBackslash(char* path)
-{
- size_t len = mir_strlen(path);
- if (len && path[len - 1] != '\\')
- mir_strcat(path, "\\");
-}
-
-/* a file transfer looks like this:
-S: 0
-R: 5
-R: 1
-S: 2
-R: 3
-S: 6 * many
-(for more files, send 2, 3, 6*many)
-*/
-
-void CIcqProto::handleFileTransferPacket(directconnect* dc, PBYTE buf, size_t wLen)
-{
- if (wLen < 1)
- return;
-
- NetLog_Direct("Handling file packet");
-
- switch (buf[0]) {
- case PEER_FILE_INIT: /* first packet of a file transfer */
- if (dc->initialised)
- return;
- if (wLen < 19)
- return;
- buf += 5; /* id, and unknown 0 */
- dc->type = DIRECTCONN_FILE;
- {
- DWORD dwFileCount;
- DWORD dwTotalSize;
- DWORD dwTransferSpeed;
- size_t wNickLength;
- int bAdded;
-
- unpackLEDWord(&buf, &dwFileCount);
- unpackLEDWord(&buf, &dwTotalSize);
- unpackLEDWord(&buf, &dwTransferSpeed);
- unpackLEWord(&buf, &wNickLength);
-
- dc->ft = FindExpectedFileRecv(dc->dwRemoteUin, dwTotalSize);
- if (dc->ft == nullptr) {
- NetLog_Direct("Unexpected file receive");
- CloseDirectConnection(dc);
- return;
- }
- dc->ft->dwFileCount = dwFileCount;
- dc->ft->dwTransferSpeed = dwTransferSpeed;
- dc->ft->hContact = HContactFromUIN(dc->ft->dwUin, &bAdded);
- dc->ft->dwBytesDone = 0;
- dc->ft->iCurrentFile = -1;
- dc->ft->fileId = -1;
- dc->ft->hConnection = dc->hConnection;
- dc->ft->dwLastNotify = GetTickCount();
-
- dc->initialised = 1;
-
- file_sendTransferSpeed(this, dc);
- file_sendNick(this, dc);
- }
- ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, dc->ft, 0);
- break;
-
- case PEER_FILE_INIT_ACK:
- if (wLen < 8)
- return;
- buf++;
- unpackLEDWord(&buf, &dc->ft->dwTransferSpeed);
- /* followed by nick */
- file_sendNextFile(this, dc);
- break;
-
- case PEER_FILE_NEXTFILE:
- if (wLen < 20)
- return;
- buf++; /* id */
- {
- size_t wThisFilenameLen, wSubdirLen;
- BYTE isDirectory;
- unpackByte(&buf, &isDirectory);
- unpackLEWord(&buf, &wThisFilenameLen);
- if (wLen < 19 + wThisFilenameLen)
- return;
-
- SAFE_FREE(&dc->ft->szThisFile);
- char *szAnsi = (char *)_alloca(wThisFilenameLen + 1);
- memcpy(szAnsi, buf, wThisFilenameLen);
- szAnsi[wThisFilenameLen] = '\0';
- dc->ft->szThisFile = ansi_to_utf8(szAnsi);
- buf += wThisFilenameLen;
-
- unpackLEWord(&buf, &wSubdirLen);
- if (wLen < 18 + wThisFilenameLen + wSubdirLen)
- return;
- SAFE_FREE(&dc->ft->szThisSubdir);
- szAnsi = (char *)_alloca(wSubdirLen + 1);
- memcpy(szAnsi, buf, wSubdirLen);
- szAnsi[wSubdirLen] = '\0';
- dc->ft->szThisSubdir = ansi_to_utf8(szAnsi);
- buf += wSubdirLen;
-
- unpackLEDWord(&buf, &dc->ft->dwThisFileSize);
- unpackLEDWord(&buf, &dc->ft->dwThisFileDate);
- unpackLEDWord(&buf, &dc->ft->dwTransferSpeed);
-
- /* no cheating with paths */
- if (!IsValidRelativePath(dc->ft->szThisFile) || !IsValidRelativePath(dc->ft->szThisSubdir)) {
- NetLog_Direct("Invalid path information");
- break;
- }
-
- char *szFullPath = (char*)SAFE_MALLOC(mir_strlen(dc->ft->szSavePath) + mir_strlen(dc->ft->szThisSubdir) + mir_strlen(dc->ft->szThisFile) + 3);
- mir_strcpy(szFullPath, dc->ft->szSavePath);
- NormalizeBackslash(szFullPath);
- mir_strcat(szFullPath, dc->ft->szThisSubdir);
- NormalizeBackslash(szFullPath);
- // _chdir(szFullPath); // set current dir - not very useful
- mir_strcat(szFullPath, dc->ft->szThisFile);
- // we joined the full path to dest file
- SAFE_FREE(&dc->ft->szThisFile);
- dc->ft->szThisFile = szFullPath;
-
- dc->ft->dwFileBytesDone = 0;
- dc->ft->iCurrentFile++;
-
- if (isDirectory) {
- MakeDirUtf(dc->ft->szThisFile);
- dc->ft->fileId = -1;
- }
- else {
- /* file resume */
- PROTOFILETRANSFERSTATUS pfts = {};
-
- file_buildProtoFileTransferStatus(dc->ft, &pfts);
- if (ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, dc->ft, (LPARAM)&pfts))
- break; /* UI supports resume: it will call PS_FILERESUME */
-
- dc->ft->fileId = OpenFileUtf(dc->ft->szThisFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE);
- if (dc->ft->fileId == -1) {
- icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder."));
- CloseDirectConnection(dc);
- dc->ft->hConnection = nullptr;
- break;
- }
- }
- }
- file_sendResume(this, dc);
- ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, dc->ft, 0);
- break;
-
- case PEER_FILE_RESUME:
- if (dc->ft->fileId == -1 && !dc->ft->currentIsDir)
- return;
- if (wLen < 13)
- return;
- if (wLen < 17)
- NetLog_Direct("Warning: Received short PEER_FILE_RESUME");
- buf++;
- {
- DWORD dwRestartFrom;
-
- unpackLEDWord(&buf, &dwRestartFrom);
- if (dwRestartFrom > dc->ft->dwThisFileSize)
- return;
- buf += 4; /* unknown. 0 */
- unpackLEDWord(&buf, &dc->ft->dwTransferSpeed);
- buf += 4; /* unknown. 1 */
- if (!dc->ft->currentIsDir)
- _lseek(dc->ft->fileId, dwRestartFrom, 0);
- dc->wantIdleTime = 1;
- dc->ft->dwBytesDone += dwRestartFrom;
- dc->ft->dwFileBytesDone += dwRestartFrom;
- }
- break;
-
- case PEER_FILE_SPEED:
- if (wLen < 5)
- return;
- buf++;
- unpackLEDWord(&buf, &dc->ft->dwTransferSpeed);
- dc->ft->dwLastNotify = GetTickCount();
- break;
-
- case PEER_FILE_DATA:
- if (!dc->ft->currentIsDir) {
- if (dc->ft->fileId == -1)
- break;
- buf++; wLen--;
- _write(dc->ft->fileId, buf, (unsigned)wLen);
- }
- else
- wLen = 0;
- dc->ft->dwBytesDone += (DWORD)wLen;
- dc->ft->dwFileBytesDone += (DWORD)wLen;
- if (GetTickCount() > dc->ft->dwLastNotify + 500 || wLen < 2048) {
- PROTOFILETRANSFERSTATUS pfts;
-
- file_buildProtoFileTransferStatus(dc->ft, &pfts);
- ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, dc->ft, (LPARAM)&pfts);
- dc->ft->dwLastNotify = GetTickCount();
- }
- if (wLen < 2048) {
- /* EOF */
- if (!dc->ft->currentIsDir)
- _close(dc->ft->fileId);
- dc->ft->fileId = -1;
- if ((DWORD)dc->ft->iCurrentFile == dc->ft->dwFileCount - 1) {
- dc->type = DIRECTCONN_CLOSING; /* this guarantees that we won't accept any more data but that the sender is still free to closesocket() neatly */
- ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dc->ft, 0);
- }
- }
- break;
-
- default:
- NetLog_Direct("Unknown file transfer packet ignored.");
- break;
- }
-}
diff --git a/protocols/IcqOscarJ/src/icq_firstrun.cpp b/protocols/IcqOscarJ/src/icq_firstrun.cpp
deleted file mode 100644
index 051d2a8974..0000000000
--- a/protocols/IcqOscarJ/src/icq_firstrun.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-static void accountLoadDetails(CIcqProto *ppro, HWND hwndDlg)
-{
- char pszUIN[20];
- DWORD dwUIN = ppro->getContactUin(NULL);
- if (dwUIN) {
- mir_snprintf(pszUIN, "%u", dwUIN);
- SetDlgItemTextA(hwndDlg, IDC_UIN, pszUIN);
- }
-
- char pszPwd[PASSWORDMAXLEN + 1];
- if (ppro->GetUserStoredPassword(pszPwd))
- SetDlgItemTextA(hwndDlg, IDC_PW, pszPwd);
-}
-
-INT_PTR CALLBACK icq_FirstRunDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
-
- ppro = (CIcqProto*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
-
- Window_SetIcon_IcoLib(hwndDlg, ppro->m_hProtoIcon);
-
- SendDlgItemMessage(hwndDlg, IDC_PW, EM_LIMITTEXT, PASSWORDMAXLEN, 0);
-
- accountLoadDetails(ppro, hwndDlg);
- return TRUE;
-
- case WM_DESTROY:
- Window_FreeIcon_IcoLib(hwndDlg);
- break;
-
- case WM_CLOSE:
- EndDialog(hwndDlg, 0);
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_REGISTER:
- Utils_OpenUrl(URL_REGISTER);
- break;
-
- case IDC_UIN:
- case IDC_PW:
- if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == GetFocus()) {
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- }
- }
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_APPLY:
- char str[128];
- GetDlgItemTextA(hwndDlg, IDC_UIN, str, _countof(str));
- ppro->setDword(UNIQUEIDSETTING, atoi(str));
-
- GetDlgItemTextA(hwndDlg, IDC_PW, str, _countof(ppro->m_szPassword));
- mir_strcpy(ppro->m_szPassword, str);
- ppro->setString("Password", str);
- break;
-
- case PSN_RESET:
- accountLoadDetails(ppro, hwndDlg);
- break;
- }
- break;
- }
-
- return FALSE;
-}
-
-INT_PTR CIcqProto::OnCreateAccMgrUI(WPARAM, LPARAM lParam)
-{
- return (INT_PTR)CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_ICQACCOUNT), (HWND)lParam, icq_FirstRunDlgProc, LPARAM(this));
-}
diff --git a/protocols/IcqOscarJ/src/icq_http.cpp b/protocols/IcqOscarJ/src/icq_http.cpp
deleted file mode 100644
index da6777799e..0000000000
--- a/protocols/IcqOscarJ/src/icq_http.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001,2002 Jon Keating, Richard Hughes
-// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004,2005,2006 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// HTTP Gateway Handling routines
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-int icq_httpGatewayInit(HNETLIBCONN hConn, NETLIBOPENCONNECTION*, NETLIBHTTPREQUEST *nlhr)
-{
- // initial response from ICQ http gateway
- size_t wLen, wVersion, wType;
- WORD wIpLen;
- DWORD dwSid1, dwSid2, dwSid3, dwSid4;
- BYTE *buf;
- char szSid[33], szHttpServer[256], szHttpGetUrl[300], szHttpPostUrl[300];
-
- if (nlhr->dataLength < 31) {
- SetLastError(ERROR_INVALID_DATA);
- return 0;
- }
-
- buf = (PBYTE)nlhr->pData;
- unpackWord(&buf, &wLen);
- unpackWord(&buf, &wVersion); /* always 0x0443 */
- unpackWord(&buf, &wType); /* hello reply */
- buf += 6; /* dunno */
- unpackDWord(&buf, &dwSid1);
- unpackDWord(&buf, &dwSid2);
- unpackDWord(&buf, &dwSid3);
- unpackDWord(&buf, &dwSid4);
- mir_snprintf(szSid, "%08x%08x%08x%08x", dwSid1, dwSid2, dwSid3, dwSid4);
- unpackWord(&buf, &wIpLen);
-
- if (nlhr->dataLength < 30 + wIpLen || wIpLen == 0 || wIpLen > sizeof(szHttpServer) - 1) {
- SetLastError(ERROR_INVALID_DATA);
- return 0;
- }
-
- SetGatewayIndex(hConn, 1); // new master connection begins here
-
- memcpy(szHttpServer, buf, wIpLen);
- szHttpServer[wIpLen] = '\0';
-
- NETLIBHTTPPROXYINFO nlhpi = {};
- nlhpi.flags = NLHPIF_USEPOSTSEQUENCE;
- nlhpi.szHttpGetUrl = szHttpGetUrl;
- nlhpi.szHttpPostUrl = szHttpPostUrl;
- nlhpi.firstPostSequence = 1;
- mir_snprintf(szHttpGetUrl, "http://%s/monitor?sid=%s", szHttpServer, szSid);
- mir_snprintf(szHttpPostUrl, "http://%s/data?sid=%s&seq=", szHttpServer, szSid);
- return Netlib_SetHttpProxyInfo(hConn, &nlhpi);
-}
-
-
-
-int icq_httpGatewayBegin(HNETLIBCONN hConn, NETLIBOPENCONNECTION* nloc)
-{ // open our "virual data connection"
- icq_packet packet;
- size_t serverNameLen;
-
- serverNameLen = mir_strlen(nloc->szHost);
-
- packet.wLen = (WORD)(serverNameLen + 4);
- write_httphdr(&packet, HTTP_PACKETTYPE_LOGIN, GetGatewayIndex(hConn));
- packWord(&packet, (WORD)serverNameLen);
- packBuffer(&packet, (LPBYTE)nloc->szHost, serverNameLen);
- packWord(&packet, nloc->wPort);
- INT_PTR res = Netlib_Send(hConn, (char*)packet.pData, packet.wLen, MSG_DUMPPROXY | MSG_NOHTTPGATEWAYWRAP);
- SAFE_FREE((void**)&packet.pData);
-
- return res != SOCKET_ERROR;
-}
-
-
-
-int icq_httpGatewayWrapSend(HNETLIBCONN hConn, PBYTE buf, int len, int flags)
-{
- PBYTE sendBuf = buf;
- int sendLen = len;
- int sendResult = 0;
-
- while (sendLen > 0) { // imitate polite behaviour of icq5.1 and split large packets
- icq_packet packet;
- WORD curLen;
- int curResult;
-
- if (sendLen > 512) curLen = 512; else curLen = (WORD)sendLen;
- // send wrapped data
- packet.wLen = curLen;
- write_httphdr(&packet, HTTP_PACKETTYPE_FLAP, GetGatewayIndex(hConn));
- packBuffer(&packet, sendBuf, curLen);
-
- curResult = Netlib_Send(hConn, (char*)packet.pData, packet.wLen, flags);
-
- SAFE_FREE((void**)&packet.pData);
-
- // sending failed, end loop
- if (curResult <= 0)
- return curResult;
- // calculare real number of data bytes sent
- if (curResult > 14) sendResult += curResult - 14;
- // move on
- sendLen -= curLen;
- sendBuf += curLen;
- }
-
- return sendResult;
-}
-
-
-
-PBYTE icq_httpGatewayUnwrapRecv(NETLIBHTTPREQUEST*, PBYTE buf, int len, int* outBufLen, void *(*)(void *, size_t))
-{
- size_t wLen, wType;
- DWORD dwPackSeq;
- PBYTE tbuf;
- size_t i = 0;
-
- tbuf = buf;
- for (;;) {
- if (tbuf - buf + 2 > len)
- break;
- unpackWord(&tbuf, &wLen);
- if (wLen < 12)
- break;
- if (tbuf - buf + wLen > (size_t)len)
- break;
- tbuf += 2; /* version */
- unpackWord(&tbuf, &wType);
- tbuf += 4; /* flags */
- unpackDWord(&tbuf, &dwPackSeq);
- if (wType == HTTP_PACKETTYPE_FLAP) { // it is normal data packet
- size_t copyBytes = wLen - 12;
- if (copyBytes > len - i) {
- /* invalid data - do our best to get something out of it */
- copyBytes = len - i;
- }
- memcpy(buf + i, tbuf, copyBytes);
- i += copyBytes;
- }
- else if (wType == HTTP_PACKETTYPE_LOGINREPLY) { // our "virtual connection" was established, good
- BYTE bRes;
-
- unpackByte(&tbuf, &bRes);
- wLen -= 1;
- if (!bRes)
- Netlib_Logf(nullptr, "Gateway Connection #%d Established.", dwPackSeq);
- else
- Netlib_Logf(nullptr, "Gateway Connection #%d Failed, error: %d", dwPackSeq, bRes);
- }
- else if (wType == HTTP_PACKETTYPE_CLOSEREPLY) { // "virtual connection" closed - only received if any other "virual connection" still active
- Netlib_Logf(nullptr, "Gateway Connection #%d Closed.", dwPackSeq);
- }
- tbuf += wLen - 12;
- }
- *outBufLen = (int)i;
-
- return buf;
-}
-
-int icq_httpGatewayWalkTo(HNETLIBCONN hConn, NETLIBOPENCONNECTION* nloc)
-{ // this is bad simplification - for avatars to work we need to handle
- // two "virtual connections" at the same time
- icq_packet packet;
- DWORD dwGatewaySeq = GetGatewayIndex(hConn);
-
- packet.wLen = 0;
- write_httphdr(&packet, HTTP_PACKETTYPE_CLOSE, dwGatewaySeq);
- Netlib_Send(hConn, (char*)packet.pData, packet.wLen, MSG_DUMPPROXY | MSG_NOHTTPGATEWAYWRAP);
- // we closed virtual connection, open new one
- dwGatewaySeq++;
- SetGatewayIndex(hConn, dwGatewaySeq);
- return icq_httpGatewayBegin(hConn, nloc);
-}
diff --git a/protocols/IcqOscarJ/src/icq_http.h b/protocols/IcqOscarJ/src/icq_http.h
deleted file mode 100644
index fb593e2977..0000000000
--- a/protocols/IcqOscarJ/src/icq_http.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001,2002 Jon Keating, Richard Hughes
-// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004,2005 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#ifndef __ICQ_HTTP_H
-#define __ICQ_HTTP_H
-
-#define HTTP_PROXY_VERSION 0x0443
-
-#define HTTP_PACKETTYPE_HELLOREPLY 2
-#define HTTP_PACKETTYPE_LOGIN 3
-#define HTTP_PACKETTYPE_LOGINREPLY 4 /* contains 1 byte: 0 */
-#define HTTP_PACKETTYPE_FLAP 5
-#define HTTP_PACKETTYPE_CLOSE 6 /* contains no data */
-#define HTTP_PACKETTYPE_CLOSEREPLY 7 /* contains 1 byte: 0 */
-
-int icq_httpGatewayInit(HNETLIBCONN hConn, NETLIBOPENCONNECTION *nloc, NETLIBHTTPREQUEST *nlhr);
-int icq_httpGatewayBegin(HNETLIBCONN hConn, NETLIBOPENCONNECTION *nloc);
-int icq_httpGatewayWrapSend(HNETLIBCONN hConn, PBYTE buf, int len, int flags);
-PBYTE icq_httpGatewayUnwrapRecv(NETLIBHTTPREQUEST *nlhr, PBYTE buf, int bufLen, int *outBufLen, void *(*NetlibRealloc)(void *, size_t));
-int icq_httpGatewayWalkTo(HNETLIBCONN hConn, NETLIBOPENCONNECTION* nloc);
-
-#endif /* __ICQ_HTTP_H */
diff --git a/protocols/IcqOscarJ/src/icq_infoupdate.cpp b/protocols/IcqOscarJ/src/icq_infoupdate.cpp
deleted file mode 100644
index 461619a54a..0000000000
--- a/protocols/IcqOscarJ/src/icq_infoupdate.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Background thread for automatic update of user details
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-// Retrieve users' info
-void CIcqProto::icq_InitInfoUpdate(void)
-{
- // Create wait objects
- hInfoQueueEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- if (hInfoQueueEvent) {
- // Init list
- for (int i = 0; i < LISTSIZE; i++) {
- m_infoUpdateList[i].dwUin = 0;
- m_infoUpdateList[i].hContact = NULL;
- m_infoUpdateList[i].queued = 0;
- }
-
- ForkThread(&CIcqProto::InfoUpdateThread, nullptr);
- }
-
- bInfoPendingUsers = 0;
- dwInfoActiveRequest = 0;
-}
-
-// Returns TRUE if user was queued
-// Returns FALSE if the list was full
-BOOL CIcqProto::icq_QueueUser(MCONTACT hContact)
-{
- if (!hInfoQueueEvent)
- return FALSE;
-
- if (nInfoUserCount >= LISTSIZE)
- return FALSE;
-
- int i, nChecked = 0, nFirstFree = -1;
-
- mir_cslock l(infoUpdateMutex);
-
- // Check if in list
- for (i = 0; (i < LISTSIZE && nChecked < nInfoUserCount); i++) {
- if (m_infoUpdateList[i].hContact) {
- nChecked++;
- if (m_infoUpdateList[i].hContact == hContact)
- return TRUE;
- }
- else if (nFirstFree == -1)
- nFirstFree = i;
- }
- if (nFirstFree == -1)
- nFirstFree = i;
-
- // Add to list
- DWORD dwUin = getContactUin(hContact);
- if (dwUin) {
- m_infoUpdateList[nFirstFree].dwUin = dwUin;
- m_infoUpdateList[nFirstFree].hContact = hContact;
- m_infoUpdateList[nFirstFree].queued = time(0);
- nInfoUserCount++;
-
- debugLogA("Queued user %u, place %u, count %u", dwUin, nFirstFree, nInfoUserCount);
-
- // Notify worker thread
- if (hInfoQueueEvent && bInfoUpdateEnabled)
- SetEvent(hInfoQueueEvent);
- }
-
- return TRUE;
-}
-
-void CIcqProto::icq_DequeueUser(DWORD dwUin)
-{
- if (nInfoUserCount > 0) {
- int nChecked = 0;
- // Check if in list
- mir_cslock l(infoUpdateMutex);
- for (int i = 0; (i < LISTSIZE && nChecked < nInfoUserCount); i++) {
- if (m_infoUpdateList[i].dwUin) {
- nChecked++;
- // Remove from list
- if (m_infoUpdateList[i].dwUin == dwUin) {
- debugLogA("Dequeued user %u", m_infoUpdateList[i].dwUin);
-
- m_infoUpdateList[i].dwUin = 0;
- m_infoUpdateList[i].hContact = NULL;
- m_infoUpdateList[i].queued = 0;
- nInfoUserCount--;
- break;
- }
- }
- }
- }
-}
-
-void CIcqProto::icq_RescanInfoUpdate()
-{
- bInfoPendingUsers = 0;
- /* This is here, cause we do not want to emit large number of reuqest at once,
- fill queue, and let thread deal with it */
- bInfoUpdateEnabled = 0; // freeze thread
-
- // Queue all outdated users
- for (auto &hContact : AccContacts())
- if (IsMetaInfoChanged(hContact)) // Queue user
- if (!icq_QueueUser(hContact)) { // The queue is full, pause queuing contacts
- bInfoPendingUsers = 1;
- break;
- }
-
- bInfoUpdateEnabled = TRUE;
-}
-
-void CIcqProto::icq_EnableUserLookup(BOOL bEnable)
-{
- bInfoUpdateEnabled = bEnable;
-
- // Notify worker thread
- if (bInfoUpdateEnabled && hInfoQueueEvent)
- SetEvent(hInfoQueueEvent);
-}
-
-void __cdecl CIcqProto::InfoUpdateThread(void*)
-{
- int i;
- DWORD dwWait = WAIT_OBJECT_0;
-
- debugLogA("%s thread starting.", "Info-Update");
- Thread_SetName("ICQ: InfoUpdateThread");
-
- bInfoUpdateRunning = TRUE;
-
- while (bInfoUpdateRunning) {
- if (!nInfoUserCount && bInfoPendingUsers) // whole queue processed, check if more users needs updating
- icq_RescanInfoUpdate();
-
- if (!nInfoUserCount || !bInfoUpdateEnabled || !icqOnline()) {
- dwWait = WAIT_TIMEOUT;
- while (bInfoUpdateRunning && dwWait == WAIT_TIMEOUT) // wait for new work or until we should end
- dwWait = ICQWaitForSingleObject(hInfoQueueEvent, 10000);
- }
- if (!bInfoUpdateRunning)
- break;
-
- switch (dwWait) {
- case WAIT_IO_COMPLETION:
- // Possible shutdown in progress
- break;
-
- case WAIT_OBJECT_0:
- case WAIT_TIMEOUT:
- // Time to check for new users
- if (!bInfoUpdateEnabled)
- continue; // we can't send requests now
-
- if (nInfoUserCount && icqOnline()) {
- time_t now = time(0);
- BOOL bNotReady = FALSE, bTimeOuted = FALSE;
-
- // Check the list, take only users that were there for at least 5sec
- // wait if any user is there shorter than 5sec and not a single user is there longer than 20sec
- {
- mir_cslock l(infoUpdateMutex);
- for (i = 0; i < LISTSIZE; i++) {
- if (m_infoUpdateList[i].hContact) {
- if (m_infoUpdateList[i].queued + 20 < now) {
- bTimeOuted = TRUE;
- break;
- }
- if (m_infoUpdateList[i].queued + 5 >= now)
- bNotReady = TRUE;
- }
- }
- }
-
- if (!bTimeOuted && bNotReady) {
- SleepEx(1000, TRUE);
- if (!bInfoUpdateRunning) { // need to end as fast as possible
- debugLogA("%s thread ended.", "Info-Update");
- goto LBL_Exit;
- }
- continue;
- }
-
- // only send another request, when the previous is completed
- if (FindCookie(dwInfoActiveRequest, nullptr, nullptr)) {
- debugLogA("Info-Update: Request 0x%x still in progress.", dwInfoActiveRequest);
-
- SleepEx(1000, TRUE);
- if (!bInfoUpdateRunning) { // need to end as fast as possible
- debugLogA("%s thread ended.", "Info-Update");
- goto LBL_Exit;
- }
- continue;
- }
-
- debugLogA("Info-Update: Users %u in queue.", nInfoUserCount);
-
- // Either some user is waiting long enough, or all users are ready (waited at least the minimum time)
- mir_cslockfull rlck(m_ratesMutex);
- if (!m_rates) // we cannot send info request - icq is offline
- break;
-
- WORD wGroup = m_rates->getGroupFromSNAC(ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST);
- while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_IDLE_30)) { // we are over rate, need to wait before sending
- int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_50);
-
- rlck.unlock();
-
- debugLogA("Rates: InfoUpdate delayed %dms", nDelay);
-
- SleepEx(nDelay, TRUE); // do not keep things locked during sleep
- if (!bInfoUpdateRunning) { // need to end as fast as possible
- debugLogA("%s thread ended.", "Info-Update");
- goto LBL_Exit;
- }
- rlck.lock();
- if (!m_rates) // we lost connection when we slept, go away
- break;
- }
- if (!m_rates) // we cannot send info request - icq is offline
- break;
-
- rlck.unlock();
-
- userinfo *hContactList[LISTSIZE];
- int nListIndex = 0;
- BYTE *pRequestData = nullptr;
- size_t nRequestSize = 0;
-
- mir_cslock l(infoUpdateMutex);
- for (i = 0; i < LISTSIZE; i++) {
- if (m_infoUpdateList[i].hContact) {
- // check TS again, maybe it has been updated while we slept
- if (IsMetaInfoChanged(m_infoUpdateList[i].hContact)) {
- if (m_infoUpdateList[i].queued + 5 < now) {
- BYTE *pItem = nullptr;
- size_t nItemSize = 0;
- DBVARIANT dbv = { DBVT_DELETED };
-
- if (!getSetting(m_infoUpdateList[i].hContact, DBSETTING_METAINFO_TOKEN, &dbv)) { // retrieve user details using privacy token
- ppackTLV(&pItem, &nItemSize, 0x96, dbv.cpbVal, dbv.pbVal);
- db_free(&dbv);
- }
- // last updated time
- ppackTLVDouble(&pItem, &nItemSize, 0x64, getSettingDouble(m_infoUpdateList[i].hContact, DBSETTING_METAINFO_TIME, 0));
-
- ppackTLVUID(&pItem, &nItemSize, 0x32, m_infoUpdateList[i].dwUin, nullptr);
- ppackWord(&pRequestData, &nRequestSize, (WORD)nItemSize);
- ppackBuffer(&pRequestData, &nRequestSize, nItemSize, pItem);
- // take a reference
- SAFE_FREE((void**)&pItem);
- hContactList[nListIndex++] = &m_infoUpdateList[i];
- }
- }
- else {
- debugLogA("Dequeued absolete user %u", m_infoUpdateList[i].dwUin);
-
- // Dequeue user and find another one
- m_infoUpdateList[i].dwUin = 0;
- m_infoUpdateList[i].hContact = NULL;
- nInfoUserCount--;
- // continue for loop
- }
- }
- }
-
- debugLogA("Request info for %u user(s).", nListIndex);
-
- if (!nListIndex) // no users to request info for
- break;
-
- if (!(dwInfoActiveRequest = sendUserInfoMultiRequest(pRequestData, nRequestSize, nListIndex))) { // sending data packet failed
- SAFE_FREE((void**)&pRequestData);
- break;
- }
- SAFE_FREE((void**)&pRequestData);
-
- for (i = 0; i < nListIndex; i++) { // Dequeue users and go back to sleep
- hContactList[i]->dwUin = 0;
- hContactList[i]->hContact = NULL;
- hContactList[i]->queued = 0;
- nInfoUserCount--;
- }
- }
- break;
-
- default:
- // Something strange happened. Exit
- bInfoUpdateRunning = FALSE;
- break;
- }
- }
-
- debugLogA("%s thread ended.", "Info-Update");
-
-LBL_Exit:
- CloseHandle(hInfoQueueEvent);
-}
-
-// Clean up before exit
-void CIcqProto::icq_InfoUpdateCleanup(void)
-{
- debugLogA("%s must die.", "Info-Update");
- bInfoUpdateRunning = FALSE;
- if (hInfoQueueEvent)
- SetEvent(hInfoQueueEvent); // break queue loop
-}
diff --git a/protocols/IcqOscarJ/src/icq_menu.cpp b/protocols/IcqOscarJ/src/icq_menu.cpp
deleted file mode 100644
index b523706b61..0000000000
--- a/protocols/IcqOscarJ/src/icq_menu.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-#include <m_skin.h>
-
-HGENMENU g_hContactMenuItems[3];
-HANDLE g_hContactMenuSvc[3];
-
-static INT_PTR IcqMenuHandleAddServContact(WPARAM wParam, LPARAM lParam)
-{
- CIcqProto* ppro = CMPlugin::getInstance(wParam);
- return (ppro) ? ppro->AddServerContact(wParam, lParam) : 0;
-}
-
-static INT_PTR IcqMenuHandleXStatusDetails(WPARAM wParam, LPARAM lParam)
-{
- CIcqProto* ppro = CMPlugin::getInstance(wParam);
- return (ppro) ? ppro->ShowXStatusDetails(wParam, lParam) : 0;
-}
-
-static INT_PTR IcqMenuHandleOpenProfile(WPARAM wParam, LPARAM lParam)
-{
- CIcqProto* ppro = CMPlugin::getInstance(wParam);
- return (ppro) ? ppro->OpenWebProfile(wParam, lParam) : 0;
-}
-
-static int IcqPrebuildContactMenu(WPARAM wParam, LPARAM lParam)
-{
- Menu_ShowItem(g_hContactMenuItems[ICMI_ADD_TO_SERVLIST], FALSE);
- Menu_ShowItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], FALSE);
- Menu_ShowItem(g_hContactMenuItems[ICMI_OPEN_PROFILE], FALSE);
-
- CIcqProto* ppro = CMPlugin::getInstance(wParam);
- return (ppro) ? ppro->OnPreBuildContactMenu(wParam, lParam) : 0;
-}
-
-void g_MenuInit(void)
-{
- ///////////////
- // Contact menu
-
- HookEvent(ME_CLIST_PREBUILDCONTACTMENU, IcqPrebuildContactMenu);
-
- // Contact menu initialization
-
- char str[MAXMODULELABELLENGTH], *pszDest = str + 3;
- mir_strcpy(str, "ICQ");
-
- CMenuItem mi(&g_plugin);
- mi.pszService = str;
-
- // "Add to server list"
- mir_strcpy(pszDest, MS_ICQ_ADDSERVCONTACT); CreateServiceFunction(str, IcqMenuHandleAddServContact);
- SET_UID(mi, 0x3928ba10, 0x69bc, 0x4ec9, 0x96, 0x48, 0xa4, 0x1b, 0xbe, 0x58, 0x4a, 0x7e);
- mi.name.a = LPGEN("Add to server list");
- mi.position = -2049999999;
- mi.hIcolibItem = Skin_GetIconHandle(SKINICON_AUTH_ADD);
- g_hContactMenuItems[ICMI_ADD_TO_SERVLIST] = Menu_AddContactMenuItem(&mi);
-
- // "Show custom status details"
- mir_strcpy(pszDest, MS_XSTATUS_SHOWDETAILS); CreateServiceFunction(str, IcqMenuHandleXStatusDetails);
- SET_UID(mi, 0x4767918b, 0x898b, 0x4cb6, 0x9c, 0x54, 0x8c, 0x56, 0x6a, 0xc4, 0xed, 0x42);
- mi.name.a = LPGEN("Show custom status details");
- mi.position = -2000004999;
- mi.hIcolibItem = nullptr;
- g_hContactMenuItems[ICMI_XSTATUS_DETAILS] = Menu_AddContactMenuItem(&mi);
-
- // "Open ICQ profile"
- mir_strcpy(pszDest, MS_OPEN_PROFILE); CreateServiceFunction(str, IcqMenuHandleOpenProfile);
- SET_UID(mi, 0x4f006492, 0x9fe5, 0x4d10, 0x88, 0xce, 0x47, 0x53, 0xba, 0x27, 0xe9, 0xc9);
- mi.name.a = LPGEN("Open ICQ profile");
- mi.position = 1000029997;
- g_hContactMenuItems[ICMI_OPEN_PROFILE] = Menu_AddContactMenuItem(&mi);
-}
-
-void g_MenuUninit(void)
-{
- Menu_RemoveItem(g_hContactMenuItems[ICMI_ADD_TO_SERVLIST]);
- Menu_RemoveItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS]);
- Menu_RemoveItem(g_hContactMenuItems[ICMI_OPEN_PROFILE]);
-}
-
-INT_PTR CIcqProto::OpenWebProfile(WPARAM hContact, LPARAM)
-{
- Utils_OpenUrl(CMStringA(FORMAT, "http://www.icq.com/people/%d", getContactUin(hContact)));
- return 0;
-}
-
-int CIcqProto::OnPreBuildContactMenu(WPARAM hContact, LPARAM)
-{
- if (hContact == NULL)
- return 0;
-
- if (icqOnline()) {
- BOOL bCtrlPressed = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
-
- DWORD dwUin = getContactUin(hContact);
-
- Menu_ShowItem(m_hmiReqAuth, dwUin && (bCtrlPressed || (getByte(hContact, "Auth", 0) && getWord(hContact, DBSETTING_SERVLIST_ID, 0))));
- Menu_ShowItem(m_hmiGrantAuth, dwUin && (bCtrlPressed || getByte(hContact, "Grant", 0)));
- Menu_ShowItem(m_hmiRevokeAuth, dwUin && (bCtrlPressed || (getByte("PrivacyItems", 0) && !getByte(hContact, "Grant", 0))));
-
- Menu_ShowItem(g_hContactMenuItems[ICMI_ADD_TO_SERVLIST],
- m_bSsiEnabled && !getWord(hContact, DBSETTING_SERVLIST_ID, 0) &&
- !getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0) &&
- !db_get_b(hContact, "CList", "NotOnList", 0));
- }
-
- Menu_ShowItem(g_hContactMenuItems[ICMI_OPEN_PROFILE], getContactUin(hContact) != 0);
- BYTE bXStatus = getContactXStatus(hContact);
-
- Menu_ShowItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], m_bHideXStatusUI ? 0 : bXStatus != 0);
- if (bXStatus && !m_bHideXStatusUI) {
- if (bXStatus > 0 && bXStatus <= XSTATUS_COUNT)
- Menu_ModifyItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], nullptr, getXStatusIcon(bXStatus, LR_SHARED));
- else
- Menu_ModifyItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], nullptr, Skin_LoadIcon(SKINICON_OTHER_SMALLDOT));
- }
-
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// OnPreBuildStatusMenu event
-
-int CIcqProto::OnPreBuildStatusMenu(WPARAM, LPARAM)
-{
- InitXStatusItems(TRUE);
- return 0;
-}
diff --git a/protocols/IcqOscarJ/src/icq_opts.cpp b/protocols/IcqOscarJ/src/icq_opts.cpp
deleted file mode 100644
index 8296a7e415..0000000000
--- a/protocols/IcqOscarJ/src/icq_opts.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-#include <win2k.h>
-
-extern BOOL bPopupService;
-
-static const wchar_t* szLogLevelDescr[] = {
- LPGENW("Display all problems"),
- LPGENW("Display problems causing possible loss of data"),
- LPGENW("Display explanations for disconnection"),
- LPGENW("Display problems requiring user intervention"),
- LPGENW("Do not display any problems (not recommended)")
-};
-
-static void LoadDBCheckState(CIcqProto* ppro, HWND hwndDlg, int idCtrl, const char* szSetting, BYTE bDef)
-{
- CheckDlgButton(hwndDlg, idCtrl, ppro->getByte(szSetting, bDef) ? BST_CHECKED : BST_UNCHECKED);
-}
-
-static void StoreDBCheckState(CIcqProto* ppro, HWND hwndDlg, int idCtrl, const char* szSetting)
-{
- ppro->setByte(szSetting, (BYTE)IsDlgButtonChecked(hwndDlg, idCtrl));
-}
-
-static void OptDlgChanged(HWND hwndDlg)
-{
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// standalone option pages
-
-static INT_PTR CALLBACK DlgProcIcqOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CIcqProto *ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
-
- ppro = (CIcqProto*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
- {
- DWORD dwUin = ppro->getContactUin(NULL);
- if (dwUin)
- SetDlgItemInt(hwndDlg, IDC_ICQNUM, dwUin, FALSE);
- else // keep it empty when no UIN entered
- SetDlgItemTextA(hwndDlg, IDC_ICQNUM, "");
-
- SendDlgItemMessage(hwndDlg, IDC_PASSWORD, EM_LIMITTEXT, PASSWORDMAXLEN, 0);
-
- // bit of a security hole here, since it's easy to extract a password from an edit box
- char pszPwd[PASSWORDMAXLEN + 1];
- if (ppro->GetUserStoredPassword(pszPwd))
- SetDlgItemTextA(hwndDlg, IDC_PASSWORD, pszPwd);
-
- LoadDBCheckState(ppro, hwndDlg, IDC_SSL, "SecureConnection", DEFAULT_SECURE_CONNECTION);
- LoadDBCheckState(ppro, hwndDlg, IDC_MD5LOGIN, "SecureLogin", DEFAULT_SECURE_LOGIN);
- LoadDBCheckState(ppro, hwndDlg, IDC_LEGACY, "LegacyFix", DEFAULT_LEGACY_FIX);
-
- char szServer[MAX_PATH];
- if (!ppro->getSettingStringStatic(NULL, "OscarServer", szServer, MAX_PATH))
- SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, szServer);
- else
- SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST);
-
- SetDlgItemInt(hwndDlg, IDC_ICQPORT, ppro->getWord("OscarPort", IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT), FALSE);
- LoadDBCheckState(ppro, hwndDlg, IDC_KEEPALIVE, "KeepAlive", DEFAULT_KEEPALIVE_ENABLED);
- SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_SETRANGE, FALSE, MAKELONG(0, 4));
- SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_SETPOS, TRUE, 4 - ppro->getByte("ShowLogLevel", LOG_WARNING));
- SetDlgItemText(hwndDlg, IDC_LEVELDESCR, TranslateW(szLogLevelDescr[4 - SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0)]));
- ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_HIDE);
- LoadDBCheckState(ppro, hwndDlg, IDC_NOERRMULTI, "IgnoreMultiErrorBox", 0);
- }
- return TRUE;
-
- case WM_HSCROLL:
- SetDlgItemText(hwndDlg, IDC_LEVELDESCR, TranslateW(szLogLevelDescr[4 - SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0)]));
- OptDlgChanged(hwndDlg);
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_LOOKUPLINK:
- Utils_OpenUrl(URL_FORGOT_PASSWORD);
- return TRUE;
-
- case IDC_NEWUINLINK:
- Utils_OpenUrl(URL_REGISTER);
- return TRUE;
-
- case IDC_RESETSERVER:
- SetDlgItemInt(hwndDlg, IDC_ICQPORT, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT, FALSE);
-
- case IDC_SSL:
- SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST);
- SetDlgItemInt(hwndDlg, IDC_ICQPORT, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT, FALSE);
- OptDlgChanged(hwndDlg);
- return TRUE;
- }
-
- if (ppro->icqOnline() && LOWORD(wParam) != IDC_NOERRMULTI) {
- char szClass[80];
- GetClassNameA((HWND)lParam, szClass, sizeof(szClass));
-
- if (mir_strcmpi(szClass, "EDIT") || HIWORD(wParam) == EN_CHANGE)
- ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_SHOW);
- }
-
- if ((LOWORD(wParam) == IDC_ICQNUM || LOWORD(wParam) == IDC_PASSWORD || LOWORD(wParam) == IDC_ICQSERVER || LOWORD(wParam) == IDC_ICQPORT) &&
- (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())) {
- return 0;
- }
-
- OptDlgChanged(hwndDlg);
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_APPLY:
- char str[128];
-
- ppro->setDword(UNIQUEIDSETTING, GetDlgItemInt(hwndDlg, IDC_ICQNUM, nullptr, FALSE));
- GetDlgItemTextA(hwndDlg, IDC_PASSWORD, str, _countof(ppro->m_szPassword));
- if (mir_strlen(str)) {
- mir_strcpy(ppro->m_szPassword, str);
- ppro->m_bRememberPwd = true;
- }
- else ppro->m_bRememberPwd = ppro->getByte("RememberPass", 0);
- ppro->setString("Password", str);
-
- GetDlgItemTextA(hwndDlg, IDC_ICQSERVER, str, _countof(str));
- ppro->setString("OscarServer", str);
-
- ppro->setWord("OscarPort", (WORD)GetDlgItemInt(hwndDlg, IDC_ICQPORT, nullptr, FALSE));
-
- StoreDBCheckState(ppro, hwndDlg, IDC_KEEPALIVE, "KeepAlive");
- StoreDBCheckState(ppro, hwndDlg, IDC_SSL, "SecureConnection");
- StoreDBCheckState(ppro, hwndDlg, IDC_MD5LOGIN, "SecureLogin");
- StoreDBCheckState(ppro, hwndDlg, IDC_LEGACY, "LegacyFix");
- StoreDBCheckState(ppro, hwndDlg, IDC_NOERRMULTI, "IgnoreMultiErrorBox");
- ppro->setByte("ShowLogLevel", (BYTE)(4 - SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0)));
- return true;
- }
- break;
- }
-
- return FALSE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static const UINT icqPrivacyControls[] = {
- IDC_DCALLOW_ANY, IDC_DCALLOW_CLIST, IDC_DCALLOW_AUTH, IDC_ADD_ANY, IDC_ADD_AUTH,
- IDC_WEBAWARE, IDC_PUBLISHPRIMARY, IDC_STATIC_DC1, IDC_STATIC_DC2, IDC_STATIC_CLIST
-};
-
-static INT_PTR CALLBACK DlgProcIcqPrivacyOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
-
- ppro = (CIcqProto*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
- {
- int nDcType = ppro->getByte("DCType", 0);
- int nAddAuth = ppro->getByte("Auth", 1);
-
- if (!ppro->icqOnline()) {
- icq_EnableMultipleControls(hwndDlg, icqPrivacyControls, _countof(icqPrivacyControls), FALSE);
- ShowDlgItem(hwndDlg, IDC_STATIC_NOTONLINE, SW_SHOW);
- }
- else ShowDlgItem(hwndDlg, IDC_STATIC_NOTONLINE, SW_HIDE);
-
- CheckDlgButton(hwndDlg, IDC_DCALLOW_ANY, (nDcType == 0) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_DCALLOW_CLIST, (nDcType == 1) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_DCALLOW_AUTH, (nDcType == 2) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_ADD_ANY, (nAddAuth == 0) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_ADD_AUTH, (nAddAuth == 1) ? BST_CHECKED : BST_UNCHECKED);
- LoadDBCheckState(ppro, hwndDlg, IDC_WEBAWARE, "WebAware", 0);
- LoadDBCheckState(ppro, hwndDlg, IDC_PUBLISHPRIMARY, "PublishPrimaryEmail", 0);
- LoadDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_CLIST, "StatusMsgReplyCList", 0);
- LoadDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_VISIBLE, "StatusMsgReplyVisible", 0);
- if (!ppro->getByte("StatusMsgReplyCList", 0))
- EnableDlgItem(hwndDlg, IDC_STATUSMSG_VISIBLE, FALSE);
- }
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_DCALLOW_ANY:
- case IDC_DCALLOW_CLIST:
- case IDC_DCALLOW_AUTH:
- case IDC_ADD_ANY:
- case IDC_ADD_AUTH:
- case IDC_WEBAWARE:
- case IDC_PUBLISHPRIMARY:
- case IDC_STATUSMSG_VISIBLE:
- if ((HWND)lParam != GetFocus()) return 0;
- break;
- case IDC_STATUSMSG_CLIST:
- if (IsDlgButtonChecked(hwndDlg, IDC_STATUSMSG_CLIST)) {
- EnableDlgItem(hwndDlg, IDC_STATUSMSG_VISIBLE, TRUE);
- LoadDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_VISIBLE, "StatusMsgReplyVisible", 0);
- }
- else {
- EnableDlgItem(hwndDlg, IDC_STATUSMSG_VISIBLE, FALSE);
- CheckDlgButton(hwndDlg, IDC_STATUSMSG_VISIBLE, BST_UNCHECKED);
- }
- break;
- default:
- return 0;
- }
- OptDlgChanged(hwndDlg);
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_APPLY:
- StoreDBCheckState(ppro, hwndDlg, IDC_WEBAWARE, "WebAware");
- StoreDBCheckState(ppro, hwndDlg, IDC_PUBLISHPRIMARY, "PublishPrimaryEmail");
- StoreDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_CLIST, "StatusMsgReplyCList");
- StoreDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_VISIBLE, "StatusMsgReplyVisible");
- if (IsDlgButtonChecked(hwndDlg, IDC_DCALLOW_AUTH))
- ppro->setByte("DCType", 2);
- else if (IsDlgButtonChecked(hwndDlg, IDC_DCALLOW_CLIST))
- ppro->setByte("DCType", 1);
- else
- ppro->setByte("DCType", 0);
- StoreDBCheckState(ppro, hwndDlg, IDC_ADD_AUTH, "Auth");
-
- if (ppro->icqOnline()) {
- PBYTE buf = nullptr;
- size_t buflen = 0;
-
- ppackTLVWord(&buf, &buflen, 0x19A, !ppro->getByte("Auth", 1));
- ppackTLVByte(&buf, &buflen, 0x212, ppro->getByte("WebAware", 0));
- ppackTLVWord(&buf, &buflen, 0x1F9, ppro->getByte("PrivacyLevel", 1));
-
- ppro->icq_changeUserDirectoryInfoServ(buf, buflen, DIRECTORYREQUEST_UPDATEPRIVACY);
-
- SAFE_FREE((void**)&buf);
-
- // Send a status packet to notify the server about the webaware setting
- WORD wStatus = MirandaStatusToIcq(ppro->m_iStatus);
-
- if (ppro->m_iStatus == ID_STATUS_INVISIBLE) {
- if (ppro->m_bSsiEnabled)
- ppro->updateServVisibilityCode(3);
- ppro->icq_setstatus(wStatus, nullptr);
- }
- else {
- ppro->icq_setstatus(wStatus, nullptr);
- if (ppro->m_bSsiEnabled)
- ppro->updateServVisibilityCode(4);
- }
- }
- return TRUE;
- }
- break;
- }
-
- return FALSE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static HWND hCpCombo;
-
-struct CPTABLE
-{
- int cpId;
- char *cpName;
-};
-
-struct CPTABLE cpTable[] = {
- { 874, LPGEN("Thai") },
- { 932, LPGEN("Japanese") },
- { 936, LPGEN("Simplified Chinese") },
- { 949, LPGEN("Korean") },
- { 950, LPGEN("Traditional Chinese") },
- { 1250, LPGEN("Central European") },
- { 1251, LPGEN("Cyrillic") },
- { 1252, LPGEN("Latin I") },
- { 1253, LPGEN("Greek") },
- { 1254, LPGEN("Turkish") },
- { 1255, LPGEN("Hebrew") },
- { 1256, LPGEN("Arabic") },
- { 1257, LPGEN("Baltic") },
- { 1258, LPGEN("Vietnamese") },
- { 1361, LPGEN("Korean (Johab)") },
- { -1, nullptr }
-};
-
-static BOOL CALLBACK FillCpCombo(LPSTR str)
-{
- int i, cp = atoi(str);
- for (i = 0; cpTable[i].cpName != nullptr && cpTable[i].cpId != cp; i++);
- if (cpTable[i].cpName)
- ComboBoxAddStringUtf(hCpCombo, cpTable[i].cpName, cpTable[i].cpId);
-
- return TRUE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static const UINT icqDCMsgControls[] = { IDC_DCPASSIVE };
-static const UINT icqXStatusControls[] = { IDC_XSTATUSAUTO };
-static const UINT icqCustomStatusControls[] = { IDC_XSTATUSRESET };
-
-static INT_PTR CALLBACK DlgProcIcqFeaturesOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
-
- ppro = (CIcqProto*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
- {
- LoadDBCheckState(ppro, hwndDlg, IDC_TEMPVISIBLE, "TempVisListEnabled", DEFAULT_TEMPVIS_ENABLED);
- LoadDBCheckState(ppro, hwndDlg, IDC_SLOWSEND, "SlowSend", DEFAULT_SLOWSEND);
- BOOL byData = ppro->getByte("DirectMessaging", DEFAULT_DCMSG_ENABLED);
- CheckDlgButton(hwndDlg, IDC_DCENABLE, byData ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_DCPASSIVE, byData == 1 ? BST_CHECKED : BST_UNCHECKED);
- icq_EnableMultipleControls(hwndDlg, icqDCMsgControls, _countof(icqDCMsgControls), byData ? TRUE : FALSE);
- BYTE byXStatusEnabled = ppro->getByte("XStatusEnabled", DEFAULT_XSTATUS_ENABLED);
- CheckDlgButton(hwndDlg, IDC_XSTATUSENABLE, byXStatusEnabled ? BST_CHECKED : BST_UNCHECKED);
- BYTE byMoodsEnabled = ppro->getByte("MoodsEnabled", DEFAULT_MOODS_ENABLED);
- CheckDlgButton(hwndDlg, IDC_MOODSENABLE, byMoodsEnabled ? BST_CHECKED : BST_UNCHECKED);
- icq_EnableMultipleControls(hwndDlg, icqXStatusControls, _countof(icqXStatusControls), byXStatusEnabled);
- icq_EnableMultipleControls(hwndDlg, icqCustomStatusControls, _countof(icqCustomStatusControls), byXStatusEnabled || byMoodsEnabled);
- LoadDBCheckState(ppro, hwndDlg, IDC_XSTATUSAUTO, "XStatusAuto", DEFAULT_XSTATUS_AUTO);
- LoadDBCheckState(ppro, hwndDlg, IDC_XSTATUSRESET, "XStatusReset", DEFAULT_XSTATUS_RESET);
- LoadDBCheckState(ppro, hwndDlg, IDC_KILLSPAMBOTS, "KillSpambots", DEFAULT_KILLSPAM_ENABLED);
-
- hCpCombo = GetDlgItem(hwndDlg, IDC_UTFCODEPAGE);
- int sCodePage = ppro->getWord("AnsiCodePage", CP_ACP);
- ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_UTFCODEPAGE), LPGEN("System default codepage"), 0);
- EnumSystemCodePagesA(FillCpCombo, CP_INSTALLED);
- if (sCodePage == 0)
- SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_SETCURSEL, 0, 0);
- else {
- for (int i = 0; i < SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_GETCOUNT, 0, 0); i++) {
- if (SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_GETITEMDATA, (WPARAM)i, 0) == sCodePage) {
- SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_SETCURSEL, (WPARAM)i, 0);
- break;
- }
- }
- }
- }
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_UTFCODEPAGE:
- if (HIWORD(wParam) == CBN_SELCHANGE)
- OptDlgChanged(hwndDlg);
- break;
- case IDC_DCENABLE:
- icq_EnableMultipleControls(hwndDlg, icqDCMsgControls, _countof(icqDCMsgControls), IsDlgButtonChecked(hwndDlg, IDC_DCENABLE));
- OptDlgChanged(hwndDlg);
- break;
- case IDC_XSTATUSENABLE:
- icq_EnableMultipleControls(hwndDlg, icqXStatusControls, _countof(icqXStatusControls), IsDlgButtonChecked(hwndDlg, IDC_XSTATUSENABLE));
- case IDC_MOODSENABLE:
- icq_EnableMultipleControls(hwndDlg, icqCustomStatusControls, _countof(icqCustomStatusControls), IsDlgButtonChecked(hwndDlg, IDC_XSTATUSENABLE) || IsDlgButtonChecked(hwndDlg, IDC_MOODSENABLE));
- default:
- OptDlgChanged(hwndDlg);
- break;
- }
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_APPLY:
- int i = SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_GETCURSEL, 0, 0);
- ppro->m_wAnsiCodepage = (WORD)SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_GETITEMDATA, (WPARAM)i, 0);
- ppro->setWord("AnsiCodePage", ppro->m_wAnsiCodepage);
-
- ppro->m_bTempVisListEnabled = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_TEMPVISIBLE);
- ppro->setByte("TempVisListEnabled", ppro->m_bTempVisListEnabled);
- StoreDBCheckState(ppro, hwndDlg, IDC_SLOWSEND, "SlowSend");
- if (IsDlgButtonChecked(hwndDlg, IDC_DCENABLE))
- ppro->m_bDCMsgEnabled = IsDlgButtonChecked(hwndDlg, IDC_DCPASSIVE) ? 1 : 2;
- else
- ppro->m_bDCMsgEnabled = 0;
- ppro->setByte("DirectMessaging", ppro->m_bDCMsgEnabled);
- ppro->m_bXStatusEnabled = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_XSTATUSENABLE);
- ppro->setByte("XStatusEnabled", ppro->m_bXStatusEnabled);
- ppro->m_bMoodsEnabled = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_MOODSENABLE);
- ppro->setByte("MoodsEnabled", ppro->m_bMoodsEnabled);
- StoreDBCheckState(ppro, hwndDlg, IDC_XSTATUSAUTO, "XStatusAuto");
- StoreDBCheckState(ppro, hwndDlg, IDC_XSTATUSRESET, "XStatusReset");
- StoreDBCheckState(ppro, hwndDlg, IDC_KILLSPAMBOTS, "KillSpambots");
- return TRUE;
- }
- break;
- }
- return FALSE;
-}
-
-static const UINT icqContactsControls[] = { IDC_ADDSERVER, IDC_LOADFROMSERVER, IDC_SAVETOSERVER, IDC_UPLOADNOW };
-static const UINT icqAvatarControls[] = { IDC_AUTOLOADAVATARS, IDC_STRICTAVATARCHECK };
-
-static INT_PTR CALLBACK DlgProcIcqContactsOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
-
- ppro = (CIcqProto*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
-
- LoadDBCheckState(ppro, hwndDlg, IDC_ENABLE, "UseServerCList", DEFAULT_SS_ENABLED);
- LoadDBCheckState(ppro, hwndDlg, IDC_ADDSERVER, "ServerAddRemove", DEFAULT_SS_ADDSERVER);
- LoadDBCheckState(ppro, hwndDlg, IDC_LOADFROMSERVER, "LoadServerDetails", DEFAULT_SS_LOAD);
- LoadDBCheckState(ppro, hwndDlg, IDC_SAVETOSERVER, "StoreServerDetails", DEFAULT_SS_STORE);
- LoadDBCheckState(ppro, hwndDlg, IDC_ENABLEAVATARS, "AvatarsEnabled", DEFAULT_AVATARS_ENABLED);
- LoadDBCheckState(ppro, hwndDlg, IDC_AUTOLOADAVATARS, "AvatarsAutoLoad", DEFAULT_LOAD_AVATARS);
- LoadDBCheckState(ppro, hwndDlg, IDC_STRICTAVATARCHECK, "StrictAvatarCheck", DEFAULT_AVATARS_CHECK);
-
- icq_EnableMultipleControls(hwndDlg, icqContactsControls, _countof(icqContactsControls), ppro->getByte("UseServerCList", DEFAULT_SS_ENABLED) ? TRUE : FALSE);
- icq_EnableMultipleControls(hwndDlg, icqAvatarControls, _countof(icqAvatarControls), ppro->getByte("AvatarsEnabled", DEFAULT_AVATARS_ENABLED) ? TRUE : FALSE);
-
- if (ppro->icqOnline()) {
- ShowDlgItem(hwndDlg, IDC_OFFLINETOENABLE, SW_SHOW);
- EnableDlgItem(hwndDlg, IDC_ENABLE, FALSE);
- EnableDlgItem(hwndDlg, IDC_ENABLEAVATARS, FALSE);
- }
- else
- EnableDlgItem(hwndDlg, IDC_UPLOADNOW, FALSE);
-
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_UPLOADNOW:
- ppro->ShowUploadContactsDialog();
- return TRUE;
- case IDC_ENABLE:
- icq_EnableMultipleControls(hwndDlg, icqContactsControls, _countof(icqContactsControls), IsDlgButtonChecked(hwndDlg, IDC_ENABLE));
- if (ppro->icqOnline())
- ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_SHOW);
- else
- EnableDlgItem(hwndDlg, IDC_UPLOADNOW, FALSE);
- break;
- case IDC_ENABLEAVATARS:
- icq_EnableMultipleControls(hwndDlg, icqAvatarControls, _countof(icqAvatarControls), IsDlgButtonChecked(hwndDlg, IDC_ENABLEAVATARS));
- break;
- }
- OptDlgChanged(hwndDlg);
- break;
-
- case WM_NOTIFY:
- if (((LPNMHDR)lParam)->code == PSN_APPLY) {
- StoreDBCheckState(ppro, hwndDlg, IDC_ENABLE, "UseServerCList");
- StoreDBCheckState(ppro, hwndDlg, IDC_ADDSERVER, "ServerAddRemove");
- StoreDBCheckState(ppro, hwndDlg, IDC_LOADFROMSERVER, "LoadServerDetails");
- StoreDBCheckState(ppro, hwndDlg, IDC_SAVETOSERVER, "StoreServerDetails");
- StoreDBCheckState(ppro, hwndDlg, IDC_ENABLEAVATARS, "AvatarsEnabled");
- StoreDBCheckState(ppro, hwndDlg, IDC_AUTOLOADAVATARS, "AvatarsAutoLoad");
- StoreDBCheckState(ppro, hwndDlg, IDC_STRICTAVATARCHECK, "StrictAvatarCheck");
- return TRUE;
- }
- break;
- }
- return FALSE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR CALLBACK DlgProcIcqPopupOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-
-int CIcqProto::OnOptionsInit(WPARAM wParam, LPARAM)
-{
- OPTIONSDIALOGPAGE odp = {};
- odp.position = -800000000;
- odp.szGroup.w = LPGENW("Network");
- odp.dwInitParam = LPARAM(this);
- odp.szTitle.w = m_tszUserName;
- odp.flags = ODPF_BOLDGROUPS | ODPF_UNICODE | ODPF_DONTTRANSLATE;
-
- odp.szTab.w = LPGENW("Account");
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQ);
- odp.pfnDlgProc = DlgProcIcqOpts;
- g_plugin.addOptions(wParam, &odp);
-
- odp.szTab.w = LPGENW("Contacts");
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQCONTACTS);
- odp.pfnDlgProc = DlgProcIcqContactsOpts;
- g_plugin.addOptions(wParam, &odp);
-
- odp.szTab.w = LPGENW("Features");
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQFEATURES);
- odp.pfnDlgProc = DlgProcIcqFeaturesOpts;
- g_plugin.addOptions(wParam, &odp);
-
- odp.szTab.w = LPGENW("Privacy");
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQPRIVACY);
- odp.pfnDlgProc = DlgProcIcqPrivacyOpts;
- g_plugin.addOptions(wParam, &odp);
-
- if (bPopupService) {
- odp.position = 100000000;
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_POPUPS);
- odp.pfnDlgProc = DlgProcIcqPopupOpts;
- odp.szGroup.w = LPGENW("Popups");
- odp.szTab.w = nullptr;
- g_plugin.addOptions(wParam, &odp);
- }
- return 0;
-}
diff --git a/protocols/IcqOscarJ/src/icq_packet.cpp b/protocols/IcqOscarJ/src/icq_packet.cpp
deleted file mode 100644
index bf57851409..0000000000
--- a/protocols/IcqOscarJ/src/icq_packet.cpp
+++ /dev/null
@@ -1,895 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-WORD generate_flap_sequence()
-{
- DWORD n = rand(), s = 0;
-
- for (DWORD i = n; i >>= 3; s += i);
-
- return (((0 - s) ^ (BYTE)n) & 7 ^ n) + 2;
-}
-
-void __fastcall init_generic_packet(icq_packet *pPacket, WORD wHeaderLen)
-{
- pPacket->wPlace = 0;
- pPacket->wLen += wHeaderLen;
- pPacket->pData = (BYTE*)SAFE_MALLOC(pPacket->wLen);
-}
-
-void write_httphdr(icq_packet *pPacket, WORD wType, DWORD dwSeq)
-{
- init_generic_packet(pPacket, 14);
-
- packWord(pPacket, (WORD)(pPacket->wLen - 2));
- packWord(pPacket, HTTP_PROXY_VERSION);
- packWord(pPacket, wType);
- packDWord(pPacket, 0); // Flags?
- packDWord(pPacket, dwSeq); // Connection sequence ?
-}
-
-void __fastcall write_flap(icq_packet *pPacket, BYTE byFlapChannel)
-{
- init_generic_packet(pPacket, 6);
-
- pPacket->nChannel = byFlapChannel;
-
- packByte(pPacket, FLAP_MARKER);
- packByte(pPacket, byFlapChannel);
- packWord(pPacket, 0); // This is the sequence ID, it is filled in during the actual sending
- packWord(pPacket, (WORD)(pPacket->wLen - 6)); // This counter should not include the flap header (thus the -6)
-}
-
-void __fastcall serverPacketInit(icq_packet *pPacket, size_t wSize)
-{
- pPacket->wLen = (WORD)wSize;
- write_flap(pPacket, ICQ_DATA_CHAN);
-}
-
-void __fastcall directPacketInit(icq_packet *pPacket, size_t dwSize)
-{
- pPacket->wPlace = 0;
- pPacket->wLen = (WORD)dwSize;
- pPacket->pData = (BYTE *)SAFE_MALLOC(dwSize + 2);
-
- packLEWord(pPacket, pPacket->wLen);
-}
-
-void __fastcall serverCookieInit(icq_packet *pPacket, BYTE *pCookie, size_t wCookieSize)
-{
- pPacket->wLen = (WORD)(wCookieSize + 8 + sizeof(CLIENT_ID_STRING) + 66);
-
- write_flap(pPacket, ICQ_LOGIN_CHAN);
- packDWord(pPacket, 0x00000001);
- packTLV(pPacket, 0x06, wCookieSize, pCookie);
-
- // Pack client identification details.
- packTLV(pPacket, 0x0003, (WORD)sizeof(CLIENT_ID_STRING) - 1, (LPBYTE)CLIENT_ID_STRING);
- packTLVWord(pPacket, 0x0017, CLIENT_VERSION_MAJOR);
- packTLVWord(pPacket, 0x0018, CLIENT_VERSION_MINOR);
- packTLVWord(pPacket, 0x0019, CLIENT_VERSION_LESSER);
- packTLVWord(pPacket, 0x001a, CLIENT_VERSION_BUILD);
- packTLVWord(pPacket, 0x0016, CLIENT_ID_CODE);
- packTLVDWord(pPacket, 0x0014, CLIENT_DISTRIBUTION);
- packTLV(pPacket, 0x000f, 0x0002, (LPBYTE)CLIENT_LANGUAGE);
- packTLV(pPacket, 0x000e, 0x0002, (LPBYTE)CLIENT_COUNTRY);
- packDWord(pPacket, 0x00940001); // reconnect flag
- packByte(pPacket, 0);
- packTLVDWord(pPacket, 0x8003, 0x00100000); // Unknown
-}
-
-void __fastcall packByte(icq_packet *pPacket, BYTE byValue)
-{
- pPacket->pData[pPacket->wPlace++] = byValue;
-}
-
-void __fastcall packWord(icq_packet *pPacket, WORD wValue)
-{
- pPacket->pData[pPacket->wPlace++] = ((wValue & 0xff00) >> 8);
- pPacket->pData[pPacket->wPlace++] = (wValue & 0x00ff);
-}
-
-void __fastcall packDWord(icq_packet *pPacket, DWORD dwValue)
-{
- pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0xff000000) >> 24);
- pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0x00ff0000) >> 16);
- pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0x0000ff00) >> 8);
- pPacket->pData[pPacket->wPlace++] = (BYTE)(dwValue & 0x000000ff);
-}
-
-void __fastcall packQWord(icq_packet *pPacket, DWORD64 qwValue)
-{
- packDWord(pPacket, (DWORD)(qwValue >> 32));
- packDWord(pPacket, (DWORD)(qwValue & 0xffffffff));
-}
-
-void packTLV(icq_packet *pPacket, WORD wType, size_t wLength, const BYTE *pbyValue)
-{
- packWord(pPacket, wType);
- packWord(pPacket, (WORD)wLength);
- packBuffer(pPacket, pbyValue, wLength);
-}
-
-void packTLVWord(icq_packet *pPacket, WORD wType, WORD wValue)
-{
- packWord(pPacket, wType);
- packWord(pPacket, 0x02);
- packWord(pPacket, wValue);
-}
-
-void packTLVDWord(icq_packet *pPacket, WORD wType, DWORD dwValue)
-{
- packWord(pPacket, wType);
- packWord(pPacket, 0x04);
- packDWord(pPacket, dwValue);
-}
-
-
-void packTLVUID(icq_packet *pPacket, WORD wType, DWORD dwUin, const char *szUid)
-{
- if (dwUin) {
- char szUin[UINMAXLEN];
-
- _ltoa(dwUin, szUin, 10);
-
- packTLV(pPacket, wType, getUINLen(dwUin), (BYTE*)szUin);
- }
- else if (szUid)
- packTLV(pPacket, wType, mir_strlen(szUid), (BYTE*)szUid);
-}
-
-
-// Pack a preformatted buffer.
-// This can be used to pack strings or any type of raw data.
-void packBuffer(icq_packet *pPacket, const BYTE* pbyBuffer, size_t wLength)
-{
- while (wLength) {
- pPacket->pData[pPacket->wPlace++] = *pbyBuffer++;
- wLength--;
- }
-}
-
-int __fastcall getUINLen(DWORD dwUin)
-{
- BYTE dwUinLen = 0;
-
- while (dwUin) {
- dwUin /= 10;
- dwUinLen += 1;
- }
- return dwUinLen;
-}
-
-int __fastcall getUIDLen(DWORD dwUin, const char *szUid)
-{
- if (dwUin)
- return getUINLen(dwUin);
-
- return (int)mir_strlen(szUid);
-}
-
-void __fastcall packUIN(icq_packet *pPacket, DWORD dwUin)
-{
- char pszUin[UINMAXLEN];
- BYTE nUinLen = getUINLen(dwUin);
-
- _ltoa(dwUin, pszUin, 10);
-
- packByte(pPacket, nUinLen); // Length of user id
- packBuffer(pPacket, (LPBYTE)pszUin, nUinLen); // Receiving user's id
-}
-
-void __fastcall packUID(icq_packet *pPacket, DWORD dwUin, const char *szUid)
-{
- if (dwUin)
- packUIN(pPacket, dwUin);
- else {
- BYTE nLen = (BYTE)mir_strlen(szUid);
- packByte(pPacket, nLen);
- packBuffer(pPacket, (LPBYTE)szUid, nLen);
- }
-}
-
-
-void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype)
-{
- packFNACHeader(pPacket, wFamily, wSubtype, 0, wSubtype << 0x10);
-}
-
-
-void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype, WORD wFlags, DWORD dwSequence)
-{
- WORD wSequence = (WORD)dwSequence & 0x7FFF; // this is necessary, if that bit is there we get disconnected
-
- packWord(pPacket, wFamily); // Family type
- packWord(pPacket, wSubtype); // Family subtype
- packWord(pPacket, wFlags); // SNAC flags
- packWord(pPacket, wSequence); // SNAC request id (sequence)
- packWord(pPacket, (WORD)(dwSequence >> 0x10)); // SNAC request id (command)
-}
-
-
-void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype, WORD wFlags, DWORD dwSequence, WORD wVersion)
-{
- packFNACHeader(pPacket, wFamily, wSubtype, wFlags | 0x8000, dwSequence);
- packWord(pPacket, 0x06);
- packTLVWord(pPacket, 0x01, wVersion);
-}
-
-
-void __fastcall packLEWord(icq_packet *pPacket, WORD wValue)
-{
- pPacket->pData[pPacket->wPlace++] = (wValue & 0x00ff);
- pPacket->pData[pPacket->wPlace++] = ((wValue & 0xff00) >> 8);
-}
-
-void __fastcall packLEDWord(icq_packet *pPacket, DWORD dwValue)
-{
- pPacket->pData[pPacket->wPlace++] = (BYTE)(dwValue & 0x000000ff);
- pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0x0000ff00) >> 8);
- pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0x00ff0000) >> 16);
- pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0xff000000) >> 24);
-}
-
-
-/* helper function to place numerics to buffer */
-static void packWord(PBYTE buf, WORD wValue)
-{
- *(buf) = ((wValue & 0xff00) >> 8);
- *(buf + 1) = (wValue & 0x00ff);
-}
-
-
-static void packDWord(PBYTE buf, DWORD dwValue)
-{
- *(buf) = (BYTE)((dwValue & 0xff000000) >> 24);
- *(buf + 1) = (BYTE)((dwValue & 0x00ff0000) >> 16);
- *(buf + 2) = (BYTE)((dwValue & 0x0000ff00) >> 8);
- *(buf + 3) = (BYTE)(dwValue & 0x000000ff);
-}
-
-
-static void packQWord(PBYTE buf, DWORD64 qwValue)
-{
- packDWord(buf, (DWORD)(qwValue >> 32));
- packDWord(buf + 4, (DWORD)(qwValue & 0xffffffff));
-}
-
-
-void ppackByte(PBYTE *buf, size_t *buflen, BYTE byValue)
-{
- *buf = (PBYTE)SAFE_REALLOC(*buf, 1 + *buflen);
- *(*buf + *buflen) = byValue;
- ++*buflen;
-}
-
-
-void ppackWord(PBYTE *buf, size_t *buflen, WORD wValue)
-{
- *buf = (PBYTE)SAFE_REALLOC(*buf, 2 + *buflen);
- packWord(*buf + *buflen, wValue);
- *buflen += 2;
-}
-
-
-void ppackLEWord(PBYTE *buf, size_t *buflen, WORD wValue)
-{
- *buf = (PBYTE)SAFE_REALLOC(*buf, 2 + *buflen);
- *(PWORD)(*buf + *buflen) = wValue;
- *buflen += 2;
-}
-
-
-void ppackLEDWord(PBYTE *buf, size_t *buflen, DWORD dwValue)
-{
- *buf = (PBYTE)SAFE_REALLOC(*buf, 4 + *buflen);
- *(PDWORD)(*buf + *buflen) = dwValue;
- *buflen += 4;
-}
-
-
-void ppackLELNTS(PBYTE *buf, size_t *buflen, const char *str)
-{
- size_t len = mir_strlen(str);
- ppackLEWord(buf, buflen, (WORD)len);
- *buf = (PBYTE)SAFE_REALLOC(*buf, *buflen + len);
- memcpy(*buf + *buflen, str, len);
- *buflen += (WORD)len;
-}
-
-
-void ppackBuffer(PBYTE *buf, size_t *buflen, size_t wLength, const BYTE *pbyValue)
-{
- if (wLength) {
- *buf = (PBYTE)SAFE_REALLOC(*buf, wLength + *buflen);
- memcpy(*buf + *buflen, pbyValue, wLength);
- *buflen += wLength;
- }
-}
-
-
-void ppackTLV(PBYTE *buf, size_t *buflen, WORD wType, size_t wLength, const BYTE *pbyValue)
-{
- *buf = (PBYTE)SAFE_REALLOC(*buf, 4 + wLength + *buflen);
- packWord(*buf + *buflen, wType);
- packWord(*buf + *buflen + 2, (WORD)wLength);
- if (wLength)
- memcpy(*buf + *buflen + 4, pbyValue, wLength);
- *buflen += 4 + wLength;
-}
-
-
-void ppackTLVByte(PBYTE *buf, size_t *buflen, WORD wType, BYTE byValue)
-{
- *buf = (PBYTE)SAFE_REALLOC(*buf, 5 + *buflen);
- packWord(*buf + *buflen, wType);
- packWord(*buf + *buflen + 2, 1);
- *(*buf + *buflen + 4) = byValue;
- *buflen += 5;
-}
-
-
-void ppackTLVWord(PBYTE *buf, size_t *buflen, WORD wType, WORD wValue)
-{
- *buf = (PBYTE)SAFE_REALLOC(*buf, 6 + *buflen);
- packWord(*buf + *buflen, wType);
- packWord(*buf + *buflen + 2, 2);
- packWord(*buf + *buflen + 4, wValue);
- *buflen += 6;
-}
-
-
-void ppackTLVDWord(PBYTE *buf, size_t *buflen, WORD wType, DWORD dwValue)
-{
- *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen);
- packWord(*buf + *buflen, wType);
- packWord(*buf + *buflen + 2, 4);
- packDWord(*buf + *buflen + 4, dwValue);
- *buflen += 8;
-}
-
-
-void ppackTLVDouble(PBYTE *buf, size_t *buflen, WORD wType, double dValue)
-{
- DWORD64 qwValue;
-
- memcpy(&qwValue, &dValue, 8);
-
- *buf = (PBYTE)SAFE_REALLOC(*buf, 12 + *buflen);
- packWord(*buf + *buflen, wType);
- packWord(*buf + *buflen + 2, 8);
- packQWord(*buf + *buflen + 4, qwValue);
- *buflen += 12;
-}
-
-
-void ppackTLVUID(PBYTE *buf, size_t *buflen, WORD wType, DWORD dwUin, const char *szUid)
-{
- if (dwUin) {
- char szUin[UINMAXLEN];
-
- _ltoa(dwUin, szUin, 10);
-
- ppackTLV(buf, buflen, wType, getUINLen(dwUin), (BYTE*)szUin);
- }
- else if (szUid)
- ppackTLV(buf, buflen, wType, mir_strlen(szUid), (BYTE*)szUid);
-}
-
-
-// *** TLV based (!!! WORDs and DWORDs are LE !!!)
-void ppackLETLVByte(PBYTE *buf, size_t *buflen, BYTE byValue, WORD wType, BYTE always)
-{
- if (!always && !byValue) return;
-
- *buf = (PBYTE)SAFE_REALLOC(*buf, 5 + *buflen);
- *(PWORD)(*buf + *buflen) = wType;
- *(PWORD)(*buf + *buflen + 2) = 1;
- *(*buf + *buflen + 4) = byValue;
- *buflen += 5;
-}
-
-
-void ppackLETLVWord(PBYTE *buf, size_t *buflen, WORD wValue, WORD wType, BYTE always)
-{
- if (!always && !wValue) return;
-
- *buf = (PBYTE)SAFE_REALLOC(*buf, 6 + *buflen);
- *(PWORD)(*buf + *buflen) = wType;
- *(PWORD)(*buf + *buflen + 2) = 2;
- *(PWORD)(*buf + *buflen + 4) = wValue;
- *buflen += 6;
-}
-
-
-void ppackLETLVDWord(PBYTE *buf, size_t *buflen, DWORD dwValue, WORD wType, BYTE always)
-{
- if (!always && !dwValue) return;
-
- *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen);
- *(PWORD)(*buf + *buflen) = wType;
- *(PWORD)(*buf + *buflen + 2) = 4;
- *(PDWORD)(*buf + *buflen + 4) = dwValue;
- *buflen += 8;
-}
-
-
-void packLETLVLNTS(PBYTE *buf, size_t *bufpos, const char *str, WORD wType)
-{
- size_t len = mir_strlen(str) + 1;
-
- *(PWORD)(*buf + *bufpos) = wType;
- *(PWORD)(*buf + *bufpos + 2) = WORD(len + 2);
- *(PWORD)(*buf + *bufpos + 4) = WORD(len);
- memcpy(*buf + *bufpos + 6, str, len);
- *bufpos += len + 6;
-}
-
-
-void ppackLETLVLNTS(PBYTE *buf, size_t *buflen, const char *str, WORD wType, BYTE always)
-{
- size_t len = mir_strlen(str) + 1;
-
- if (!always && len < 2) return;
-
- *buf = (PBYTE)SAFE_REALLOC(*buf, 6 + *buflen + len);
- packLETLVLNTS(buf, buflen, str, wType);
-}
-
-
-void ppackLETLVWordLNTS(PBYTE *buf, size_t *buflen, WORD w, const char *str, WORD wType, BYTE always)
-{
- size_t len = mir_strlen(str) + 1;
-
- if (!always && len < 2 && !w) return;
-
- *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen + len);
- *(PWORD)(*buf + *buflen) = wType;
- *(PWORD)(*buf + *buflen + 2) = WORD(len + 4);
- *(PWORD)(*buf + *buflen + 4) = w;
- *(PWORD)(*buf + *buflen + 6) = WORD(len);
- memcpy(*buf + *buflen + 8, str, len);
- *buflen += len + 8;
-}
-
-
-void ppackLETLVLNTSByte(PBYTE *buf, size_t *buflen, const char *str, BYTE b, WORD wType)
-{
- size_t len = mir_strlen(str) + 1;
-
- *buf = (PBYTE)SAFE_REALLOC(*buf, 7 + *buflen + len);
- *(PWORD)(*buf + *buflen) = wType;
- *(PWORD)(*buf + *buflen + 2) = WORD(len + 3);
- *(PWORD)(*buf + *buflen + 4) = WORD(len);
- memcpy(*buf + *buflen + 6, str, len);
- *(*buf + *buflen + 6 + len) = b;
- *buflen += len + 7;
-}
-
-
-void CIcqProto::ppackLETLVLNTSfromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType)
-{
- char szTmp[1024];
- char *str = "";
-
- if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp)))
- str = szTmp;
-
- ppackLETLVLNTS(buf, buflen, str, wType, 1);
-}
-
-void CIcqProto::ppackLETLVWordLNTSfromDB(PBYTE *buf, size_t *buflen, WORD w, const char *szSetting, WORD wType)
-{
- char szTmp[1024];
- char *str = "";
-
- if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp)))
- str = szTmp;
-
- ppackLETLVWordLNTS(buf, buflen, w, str, wType, 1);
-}
-
-void CIcqProto::ppackLETLVLNTSBytefromDB(PBYTE *buf, size_t *buflen, const char *szSetting, BYTE b, WORD wType)
-{
- char szTmp[1024];
- char *str = "";
-
- if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp)))
- str = szTmp;
-
- ppackLETLVLNTSByte(buf, buflen, str, b, wType);
-}
-
-
-void CIcqProto::ppackTLVStringFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType)
-{
- char szTmp[1024];
- char *str = "";
-
- if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp)))
- str = szTmp;
-
- ppackTLV(buf, buflen, wType, mir_strlen(str), (PBYTE)str);
-}
-
-
-void CIcqProto::ppackTLVStringUtfFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType)
-{
- char *str = getSettingStringUtf(NULL, szSetting, nullptr);
-
- ppackTLV(buf, buflen, wType, mir_strlen(str), (PBYTE)str);
-
- SAFE_FREE((void**)&str);
-}
-
-
-void CIcqProto::ppackTLVDateFromDB(PBYTE *buf, size_t *buflen, const char *szSettingYear, const char *szSettingMonth, const char *szSettingDay, WORD wType)
-{
- SYSTEMTIME sTime = { 0 };
- double time = 0;
-
- sTime.wYear = getWord(szSettingYear, 0);
- sTime.wMonth = getByte(szSettingMonth, 0);
- sTime.wDay = getByte(szSettingDay, 0);
- if (sTime.wYear || sTime.wMonth || sTime.wDay) {
- SystemTimeToVariantTime(&sTime, &time);
- time -= 2;
- }
-
- ppackTLVDouble(buf, buflen, wType, time);
-}
-
-
-int CIcqProto::ppackTLVWordStringItemFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wTypeID, WORD wTypeData, WORD wID)
-{
- char szTmp[1024];
- char *str = nullptr;
-
- if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp)))
- str = szTmp;
-
- if (str) {
- size_t wLen = mir_strlen(str);
-
- ppackWord(buf, buflen, WORD(wLen + 0x0A));
- ppackTLVWord(buf, buflen, wTypeID, wID);
- ppackTLV(buf, buflen, wTypeData, wLen, (PBYTE)str);
-
- return 1; // Success
- }
-
- return 0; // No data
-}
-
-
-int CIcqProto::ppackTLVWordStringUtfItemFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wTypeID, WORD wTypeData, WORD wID)
-{
- char *str = getSettingStringUtf(NULL, szSetting, nullptr);
-
- if (str) {
- size_t wLen = mir_strlen(str);
-
- ppackWord(buf, buflen, WORD(wLen + 0x0A));
- ppackTLVWord(buf, buflen, wTypeID, wID);
- ppackTLV(buf, buflen, wTypeData, wLen, (PBYTE)str);
-
- SAFE_FREE(&str);
-
- return 1; // Success
- }
-
- return 0; // No data
-}
-
-
-void ppackTLVBlockItems(PBYTE *buf, size_t *buflen, WORD wType, int *nItems, PBYTE *pBlock, WORD *wLength, BOOL bSingleItem)
-{
- *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen + *wLength);
- packWord(*buf + *buflen, wType);
- packWord(*buf + *buflen + 2, (bSingleItem ? 4 : 2) + *wLength);
- packWord(*buf + *buflen + 4, *nItems);
- if (bSingleItem)
- packWord(*buf + *buflen + 6, *wLength);
- if (*wLength)
- memcpy(*buf + *buflen + (bSingleItem ? 8 : 6), *pBlock, *wLength);
- *buflen += (bSingleItem ? 8 : 6) + *wLength;
-
- SAFE_FREE((void**)pBlock);
- *wLength = 0;
- *nItems = 0;
-}
-
-
-void ppackTLVBlockItem(PBYTE *buf, size_t *buflen, WORD wType, PBYTE *pItem, WORD *wLength)
-{
- if (wLength) {
- *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen + *wLength);
- packWord(*buf + *buflen, wType);
- packWord(*buf + *buflen + 2, 4 + *wLength);
- packWord(*buf + *buflen + 4, 1);
- packWord(*buf + *buflen + 6, *wLength);
- memcpy(*buf + *buflen + 8, *pItem, *wLength);
- *buflen += 8 + *wLength;
- *wLength = 0;
- }
- else {
- *buf = (PBYTE)SAFE_REALLOC(*buf, 6 + *buflen);
- packWord(*buf + *buflen, wType);
- packWord(*buf + *buflen + 2, 0x02);
- packWord(*buf + *buflen + 4, 0);
- *buflen += 6;
- }
-
- SAFE_FREE((void**)pItem);
-}
-
-
-void __fastcall unpackByte(BYTE **pSource, BYTE *byDestination)
-{
- if (byDestination)
- *byDestination = *(*pSource)++;
- else
- (*pSource)++;
-}
-
-void __fastcall unpackWord(BYTE **pSource, WORD *wDestination)
-{
- BYTE *tmp = *pSource;
-
- if (wDestination) {
- *wDestination = *tmp++ << 8;
- *wDestination |= *tmp++;
-
- *pSource = tmp;
- }
- else *pSource += 2;
-}
-
-void __fastcall unpackWord(BYTE **pSource, size_t *wDestination)
-{
- BYTE *tmp = *pSource;
-
- if (wDestination) {
- *wDestination = *tmp++ << 8;
- *wDestination |= *tmp++;
-
- *pSource = tmp;
- }
- else *pSource += 2;
-}
-
-void __fastcall unpackDWord(BYTE **pSource, DWORD *dwDestination)
-{
- BYTE *tmp = *pSource;
-
- if (dwDestination) {
- *dwDestination = *tmp++ << 24;
- *dwDestination |= *tmp++ << 16;
- *dwDestination |= *tmp++ << 8;
- *dwDestination |= *tmp++;
-
- *pSource = tmp;
- }
- else *pSource += 4;
-}
-
-void __fastcall unpackQWord(BYTE **pSource, DWORD64 *qwDestination)
-{
- DWORD dwData;
-
- if (qwDestination) {
- unpackDWord(pSource, &dwData);
- *qwDestination = ((DWORD64)dwData) << 32;
- unpackDWord(pSource, &dwData);
- *qwDestination |= dwData;
- }
- else
- *pSource += 8;
-}
-
-void __fastcall unpackLEWord(BYTE **buf, WORD *w)
-{
- BYTE *tmp = *buf;
-
- if (w) {
- *w = (*tmp++);
- *w |= ((*tmp++) << 8);
- }
- else tmp += 2;
-
- *buf = tmp;
-}
-
-void __fastcall unpackLEWord(BYTE **buf, size_t *w)
-{
- BYTE *tmp = *buf;
-
- if (w) {
- *w = (*tmp++);
- *w |= ((*tmp++) << 8);
- }
- else tmp += 2;
-
- *buf = tmp;
-}
-
-void __fastcall unpackLEDWord(BYTE **buf, DWORD *dw)
-{
- BYTE *tmp = *buf;
-
- if (dw) {
- *dw = (*tmp++);
- *dw |= ((*tmp++) << 8);
- *dw |= ((*tmp++) << 16);
- *dw |= ((*tmp++) << 24);
- }
- else tmp += 4;
-
- *buf = tmp;
-}
-
-void __fastcall unpackLEDWord(BYTE **buf, size_t *dw)
-{
- BYTE *tmp = *buf;
-
- if (dw) {
- *dw = (*tmp++);
- *dw |= ((*tmp++) << 8);
- *dw |= ((*tmp++) << 16);
- *dw |= ((*tmp++) << 24);
- }
- else tmp += 4;
-
- *buf = tmp;
-}
-
-void unpackString(BYTE **buf, char *string, size_t len)
-{
- BYTE *tmp = *buf;
-
- if (string) {
- while (len) /* Can have 0x00 so go by len */
- {
- *string++ = *tmp++;
- len--;
- }
- }
- else
- tmp += len;
-
- *buf = tmp;
-}
-
-void unpackWideString(BYTE **buf, WCHAR *string, size_t len)
-{
- BYTE *tmp = *buf;
-
- while (len > 1) {
- *string = (*tmp++ << 8);
- *string |= *tmp++;
-
- string++;
- len -= 2;
- }
-
- // We have a stray byte at the end, this means that the buffer had an odd length
- // which indicates an error.
- _ASSERTE(len == 0);
- if (len != 0) {
- // We dont copy the last byte but we still need to increase the buffer pointer
- // (we assume that 'len' was correct) since the calling function expects
- // that it is increased 'len' bytes.
- *tmp += (BYTE)len;
- }
-
- *buf = tmp;
-}
-
-void unpackTypedTLV(BYTE *buf, size_t buflen, WORD type, WORD *ttype, size_t *tlen, BYTE **ttlv)
-{
- WORD wType;
- size_t wLen;
-
-NextTLV:
- // Unpack type and length
- unpackWord(&buf, &wType);
- unpackWord(&buf, &wLen);
- buflen -= 4;
-
- if (wType != type && buflen >= wLen + 4) { // Not the right TLV, try next
- buflen -= wLen;
- buf += wLen;
- goto NextTLV;
- }
- // Check buffer size
- if (wLen > buflen) wLen = buflen;
-
- // Make sure we have a good pointer
- if (ttlv) {
- if (wLen) { // Unpack and save value
- *ttlv = (BYTE*)SAFE_MALLOC(wLen + 1); // Add 1 for \0
- unpackString(&buf, (char*)*ttlv, wLen);
- *(*ttlv + wLen) = '\0';
- }
- else
- *ttlv = nullptr;
- }
-
- // Save type and length
- if (ttype)
- *ttype = wType;
- if (tlen)
- *tlen = wLen;
-}
-
-
-BOOL CIcqProto::unpackUID(BYTE **ppBuf, size_t *pwLen, DWORD *pdwUIN, uid_str *ppszUID)
-{
- // sanity check
- if (!ppBuf || !pwLen || *pwLen < 1)
- return FALSE;
-
- // Sender UIN
- BYTE nUIDLen;
- unpackByte(ppBuf, &nUIDLen);
- *pwLen -= 1;
-
- if ((nUIDLen > *pwLen) || (nUIDLen == 0))
- return FALSE;
-
- if (nUIDLen <= UINMAXLEN) { // it can be uin, check
- char szUIN[UINMAXLEN + 1];
-
- unpackString(ppBuf, szUIN, nUIDLen);
- szUIN[nUIDLen] = '\0';
- *pwLen -= nUIDLen;
-
- if (IsStringUIN(szUIN)) {
- *pdwUIN = atoi(szUIN);
- return TRUE;
- }
- else { // go back
- *ppBuf -= nUIDLen;
- *pwLen += nUIDLen;
- }
- }
- if (!ppszUID || !(*ppszUID)) { // skip the UID data
- *ppBuf += nUIDLen;
- *pwLen -= nUIDLen;
-
- debugLogA("Malformed UIN in packet");
- return FALSE;
- }
-
- unpackString(ppBuf, *ppszUID, nUIDLen);
- *pwLen -= nUIDLen;
- (*ppszUID)[nUIDLen] = '\0';
-
- *pdwUIN = 0; // this is how we determine aim contacts internally
-
- return TRUE;
-}
diff --git a/protocols/IcqOscarJ/src/icq_packet.h b/protocols/IcqOscarJ/src/icq_packet.h
deleted file mode 100644
index 21be92ed30..0000000000
--- a/protocols/IcqOscarJ/src/icq_packet.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#ifndef __ICQ_PACKET_H
-#define __ICQ_PACKET_H
-
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef unsigned long DWORD;
-
-/*---------* Structures *--------------*/
-
-struct icq_packet
-{
- WORD wPlace;
- BYTE nChannel;
- WORD wLen;
- BYTE *pData;
-};
-
-/*---------* Functions *---------------*/
-
-WORD generate_flap_sequence();
-
-void __fastcall init_generic_packet(icq_packet *pPacket, WORD wHeaderLen);
-void write_httphdr(icq_packet *pPacket, WORD wType, DWORD dwSeq);
-void __fastcall write_flap(icq_packet *pPacket, BYTE byFlapChannel);
-void __fastcall serverPacketInit(icq_packet *pPacket, size_t cbSize);
-void __fastcall directPacketInit(icq_packet *pPacket, size_t cbSize);
-
-void __fastcall serverCookieInit(icq_packet *pPacket, BYTE *pCookie, size_t wCookieSize);
-
-void __fastcall packByte(icq_packet *pPacket, BYTE byValue);
-void __fastcall packWord(icq_packet *pPacket, WORD wValue);
-void __fastcall packDWord(icq_packet *pPacket, DWORD dwValue);
-void __fastcall packQWord(icq_packet *pPacket, DWORD64 qwValue);
-void packTLV(icq_packet *pPacket, WORD wType, size_t wLength, const BYTE *pbyValue);
-void packTLVWord(icq_packet *pPacket, WORD wType, WORD wData);
-void packTLVDWord(icq_packet *pPacket, WORD wType, DWORD dwData);
-void packTLVUID(icq_packet *pPacket, WORD wType, DWORD dwUin, const char *szUid);
-
-void packBuffer(icq_packet *pPacket, const BYTE *pbyBuffer, size_t wLength);
-
-int __fastcall getUINLen(DWORD dwUin);
-int __fastcall getUIDLen(DWORD dwUin, const char *szUid);
-void __fastcall packUIN(icq_packet *pPacket, DWORD dwUin);
-void __fastcall packUID(icq_packet *pPacket, DWORD dwUin, const char *szUid);
-
-void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype);
-void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype, WORD wFlags, DWORD dwSequence);
-void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype, WORD wFlags, DWORD dwSequence, WORD wVersion);
-
-void __fastcall packLEWord(icq_packet *pPacket, WORD wValue);
-void __fastcall packLEDWord(icq_packet *pPacket, DWORD dwValue);
-
-void packLETLVLNTS(PBYTE *buf, size_t *bufpos, const char *str, WORD wType);
-
-void ppackByte(PBYTE *buf, size_t *buflen, BYTE byValue);
-void ppackWord(PBYTE *buf, size_t *buflen, WORD wValue);
-void ppackLEWord(PBYTE *buf, size_t *buflen, WORD wValue);
-void ppackLEDWord(PBYTE *buf, size_t *buflen, DWORD dwValue);
-void ppackLELNTS(PBYTE *buf, size_t *buflen, const char *str);
-void ppackBuffer(PBYTE *buf, size_t *buflen, size_t wLength, const BYTE *pbyValue);
-
-void ppackTLV(PBYTE *buf, size_t *buflen, WORD wType, size_t wLength, const BYTE *pbyValue);
-void ppackTLVByte(PBYTE *buf, size_t *buflen, WORD wType, BYTE byValue);
-void ppackTLVWord(PBYTE *buf, size_t *buflen, WORD wType, WORD wValue);
-void ppackTLVDWord(PBYTE *buf, size_t *buflen, WORD wType, DWORD dwValue);
-void ppackTLVDouble(PBYTE *buf, size_t *buflen, WORD wType, double dValue);
-void ppackTLVUID(PBYTE *buf, size_t *buflen, WORD wType, DWORD dwUin, const char *szUid);
-
-void ppackLETLVByte(PBYTE *buf, size_t *buflen, BYTE byValue, WORD wType, BYTE always);
-void ppackLETLVWord(PBYTE *buf, size_t *buflen, WORD wValue, WORD wType, BYTE always);
-void ppackLETLVDWord(PBYTE *buf, size_t *buflen, DWORD dwValue, WORD wType, BYTE always);
-void ppackLETLVLNTS(PBYTE *buf, size_t *buflen, const char *str, WORD wType, BYTE always);
-void ppackLETLVWordLNTS(PBYTE *buf, size_t *buflen, WORD w, const char *str, WORD wType, BYTE always);
-void ppackLETLVLNTSByte(PBYTE *buf, size_t *buflen, const char *str, BYTE b, WORD wType);
-
-void ppackTLVBlockItems(PBYTE *buf, size_t *buflen, WORD wType, int *nItems, PBYTE *pBlock, WORD *wLength, BOOL bSingleItem);
-void ppackTLVBlockItem(PBYTE *buf, size_t *buflen, WORD wType, PBYTE *pItem, WORD *wLength);
-
-void __fastcall unpackByte(BYTE **pSource, BYTE *byDestination);
-void __fastcall unpackWord(BYTE **pSource, WORD *wDestination);
-void __fastcall unpackWord(BYTE **pSource, size_t *wDestination);
-void __fastcall unpackDWord(BYTE **pSource, DWORD *dwDestination);
-void __fastcall unpackQWord(BYTE **pSource, DWORD64 *qwDestination);
-void unpackString(BYTE **buf, char *string, size_t len);
-void unpackWideString(BYTE **buf, WCHAR *string, size_t len);
-void unpackTypedTLV(BYTE *buf, size_t buflen, WORD type, WORD *ttype, size_t *tlen, BYTE **ttlv);
-BOOL unpackUID(BYTE **ppBuf, WORD *pwLen, DWORD *pdwUIN, uid_str *ppszUID);
-
-void __fastcall unpackLEWord(BYTE **buf, WORD *w);
-void __fastcall unpackLEWord(BYTE **buf, size_t *w);
-
-void __fastcall unpackLEDWord(BYTE **buf, DWORD *dw);
-void __fastcall unpackLEDWord(BYTE **buf, size_t *dw);
-
-#endif /* __ICQ_PACKET_H */
diff --git a/protocols/IcqOscarJ/src/icq_popups.cpp b/protocols/IcqOscarJ/src/icq_popups.cpp
deleted file mode 100644
index 2e824c9ff1..0000000000
--- a/protocols/IcqOscarJ/src/icq_popups.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Popup Plugin stuff
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-extern BOOL bPopupService;
-
-static const UINT icqPopupsControls[] = {
- IDC_POPUPS_LOG_ENABLED, IDC_POPUPS_SPAM_ENABLED, IDC_PREVIEW, IDC_USESYSICONS, IDC_POPUP_LOG0_TIMEOUT,
- IDC_POPUP_LOG1_TIMEOUT, IDC_POPUP_LOG2_TIMEOUT, IDC_POPUP_LOG3_TIMEOUT, IDC_POPUP_SPAM_TIMEOUT
-};
-
-static const UINT icqPopupColorControls[] = {
- IDC_POPUP_LOG0_TEXTCOLOR, IDC_POPUP_LOG1_TEXTCOLOR, IDC_POPUP_LOG2_TEXTCOLOR, IDC_POPUP_LOG3_TEXTCOLOR, IDC_POPUP_SPAM_TEXTCOLOR,
- IDC_POPUP_LOG0_BACKCOLOR, IDC_POPUP_LOG1_BACKCOLOR, IDC_POPUP_LOG2_BACKCOLOR, IDC_POPUP_LOG3_BACKCOLOR, IDC_POPUP_SPAM_BACKCOLOR
-};
-
-INT_PTR CALLBACK DlgProcIcqPopupOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- static bool bInitDone = true;
- BYTE bEnabled;
- CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- bInitDone = false;
- TranslateDialogDefault(hwndDlg);
-
- ppro = (CIcqProto*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
-
- CheckDlgButton(hwndDlg, IDC_POPUPS_LOG_ENABLED, ppro->getByte(NULL, "PopupsLogEnabled", DEFAULT_LOG_POPUPS_ENABLED) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_POPUPS_SPAM_ENABLED, ppro->getByte(NULL, "PopupsSpamEnabled", DEFAULT_SPAM_POPUPS_ENABLED) ? BST_CHECKED : BST_UNCHECKED);
- SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG0_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups0TextColor", DEFAULT_LOG0_TEXT_COLORS));
- SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG0_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups0BackColor", DEFAULT_LOG0_BACK_COLORS));
- SetDlgItemInt(hwndDlg, IDC_POPUP_LOG0_TIMEOUT, ppro->getDword(NULL, "Popups0Timeout", DEFAULT_LOG0_TIMEOUT), FALSE);
- SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG1_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups1TextColor", DEFAULT_LOG1_TEXT_COLORS));
- SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG1_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups1BackColor", DEFAULT_LOG1_BACK_COLORS));
- SetDlgItemInt(hwndDlg, IDC_POPUP_LOG1_TIMEOUT, ppro->getDword(NULL, "Popups1Timeout", DEFAULT_LOG1_TIMEOUT), FALSE);
- SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG2_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups2TextColor", DEFAULT_LOG2_TEXT_COLORS));
- SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG2_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups2BackColor", DEFAULT_LOG2_BACK_COLORS));
- SetDlgItemInt(hwndDlg, IDC_POPUP_LOG2_TIMEOUT, ppro->getDword(NULL, "Popups2Timeout", DEFAULT_LOG2_TIMEOUT), FALSE);
- SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG3_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups3TextColor", DEFAULT_LOG3_TEXT_COLORS));
- SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG3_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups3BackColor", DEFAULT_LOG3_BACK_COLORS));
- SetDlgItemInt(hwndDlg, IDC_POPUP_LOG3_TIMEOUT, ppro->getDword(NULL, "Popups3Timeout", DEFAULT_LOG3_TIMEOUT), FALSE);
- SendDlgItemMessage(hwndDlg, IDC_POPUP_SPAM_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "PopupsSpamTextColor", DEFAULT_SPAM_TEXT_COLORS));
- SendDlgItemMessage(hwndDlg, IDC_POPUP_SPAM_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "PopupsSpamBackColor", DEFAULT_SPAM_BACK_COLORS));
- SetDlgItemInt(hwndDlg, IDC_POPUP_SPAM_TIMEOUT, ppro->getDword(NULL, "PopupsSpamTimeout", DEFAULT_SPAM_TIMEOUT), FALSE);
- bEnabled = ppro->getByte(NULL, "PopupsWinColors", DEFAULT_POPUPS_WIN_COLORS);
- CheckDlgButton(hwndDlg, IDC_USEWINCOLORS, bEnabled ? BST_CHECKED : BST_UNCHECKED);
- bEnabled |= ppro->getByte(NULL, "PopupsDefColors", DEFAULT_POPUPS_DEF_COLORS);
- CheckDlgButton(hwndDlg, IDC_USEDEFCOLORS, bEnabled ? BST_CHECKED : BST_UNCHECKED);
- icq_EnableMultipleControls(hwndDlg, icqPopupColorControls, _countof(icqPopupColorControls), bEnabled);
- CheckDlgButton(hwndDlg, IDC_USESYSICONS, ppro->getByte(NULL, "PopupsSysIcons", DEFAULT_POPUPS_SYS_ICONS) ? BST_CHECKED : BST_UNCHECKED);
- bEnabled = ppro->getByte(NULL, "PopupsEnabled", DEFAULT_POPUPS_ENABLED);
- CheckDlgButton(hwndDlg, IDC_POPUPS_ENABLED, bEnabled ? BST_CHECKED : BST_UNCHECKED);
- icq_EnableMultipleControls(hwndDlg, icqPopupsControls, _countof(icqPopupsControls), bEnabled);
- if (bEnabled) {
- if (IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS)) {
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), !WM_ENABLE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), WM_ENABLE);
- }
- else {
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), WM_ENABLE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), !WM_ENABLE);
- }
- }
- icq_EnableMultipleControls(hwndDlg, icqPopupColorControls, _countof(icqPopupColorControls), bEnabled & (BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_USEWINCOLORS) && BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS)));
- bInitDone = true;
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_PREVIEW:
- {
- ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Note"), LOG_NOTE);
- ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Warning"), LOG_WARNING);
- ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Error"), LOG_ERROR);
- ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Fatal"), LOG_FATAL);
- ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Spambot"), POPTYPE_SPAM);
- }
- return FALSE;
-
- case IDC_POPUPS_ENABLED:
- bEnabled = IsDlgButtonChecked(hwndDlg, IDC_POPUPS_ENABLED);
- if (bEnabled) {
- if (IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS)) {
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), !WM_ENABLE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), WM_ENABLE);
- }
- else {
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), WM_ENABLE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), !WM_ENABLE);
- }
- }
- else {
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), !WM_ENABLE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), !WM_ENABLE);
- }
- icq_EnableMultipleControls(hwndDlg, icqPopupsControls, _countof(icqPopupsControls), bEnabled);
-
- case IDC_USEWINCOLORS:
- bEnabled = IsDlgButtonChecked(hwndDlg, IDC_POPUPS_ENABLED);
- if (bEnabled) {
- if (IsDlgButtonChecked(hwndDlg, IDC_USEWINCOLORS))
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), !WM_ENABLE);
- else
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), WM_ENABLE);
- }
- icq_EnableMultipleControls(hwndDlg, icqPopupColorControls, _countof(icqPopupColorControls), !IsDlgButtonChecked(hwndDlg, IDC_USEWINCOLORS));
-
- case IDC_USEDEFCOLORS:
- bEnabled = IsDlgButtonChecked(hwndDlg, IDC_POPUPS_ENABLED);
- if (bEnabled) {
- if (IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS))
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), !WM_ENABLE);
- else
- EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), WM_ENABLE);
- }
- icq_EnableMultipleControls(hwndDlg, icqPopupColorControls, _countof(icqPopupColorControls), !IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS));
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
-
- case IDC_POPUP_LOG0_TIMEOUT:
- case IDC_POPUP_LOG1_TIMEOUT:
- case IDC_POPUP_LOG2_TIMEOUT:
- case IDC_POPUP_LOG3_TIMEOUT:
- case IDC_POPUP_SPAM_TIMEOUT:
- if ((HIWORD(wParam) == EN_CHANGE) && bInitDone)
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- default:
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- }
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_APPLY:
- ppro->setByte("PopupsEnabled", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_POPUPS_ENABLED));
- ppro->setByte("PopupsLogEnabled", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_POPUPS_LOG_ENABLED));
- ppro->setByte("PopupsSpamEnabled", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_POPUPS_SPAM_ENABLED));
- ppro->setDword("Popups0TextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG0_TEXTCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("Popups0BackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG0_BACKCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("Popups0Timeout", GetDlgItemInt(hwndDlg, IDC_POPUP_LOG0_TIMEOUT, nullptr, FALSE));
- ppro->setDword("Popups1TextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG1_TEXTCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("Popups1BackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG1_BACKCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("Popups1Timeout", GetDlgItemInt(hwndDlg, IDC_POPUP_LOG1_TIMEOUT, nullptr, FALSE));
- ppro->setDword("Popups2TextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG2_TEXTCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("Popups2BackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG2_BACKCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("Popups2Timeout", GetDlgItemInt(hwndDlg, IDC_POPUP_LOG2_TIMEOUT, nullptr, FALSE));
- ppro->setDword("Popups3TextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG3_TEXTCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("Popups3BackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG3_BACKCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("Popups3Timeout", GetDlgItemInt(hwndDlg, IDC_POPUP_LOG3_TIMEOUT, nullptr, FALSE));
- ppro->setDword("PopupsSpamTextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_SPAM_TEXTCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("PopupsSpamBackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_SPAM_BACKCOLOR, CPM_GETCOLOUR, 0, 0));
- ppro->setDword("PopupsSpamTimeout", GetDlgItemInt(hwndDlg, IDC_POPUP_SPAM_TIMEOUT, nullptr, FALSE));
- ppro->setByte("PopupsWinColors", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_USEWINCOLORS));
- ppro->setByte("PopupsDefColors", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS));
- ppro->setByte("PopupsSysIcons", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_USESYSICONS));
- return TRUE;
- }
- break;
- }
- return FALSE;
-}
-
-int CIcqProto::ShowPopupMsg(MCONTACT hContact, const char *szTitle, const char *szMsg, BYTE bType)
-{
- if (bPopupService && getByte("PopupsEnabled", DEFAULT_POPUPS_ENABLED)) {
- POPUPDATAT ppd = { 0 };
- LPWSTR rsIcon;
- char szPrefix[32], szSetting[32];
- mir_strcpy(szPrefix, "Popups");
-
- switch (bType) {
- case LOG_NOTE:
- rsIcon = IDI_INFORMATION;
- ppd.colorBack = DEFAULT_LOG0_BACK_COLORS;
- ppd.colorText = DEFAULT_LOG0_TEXT_COLORS;
- mir_strcat(szPrefix, "0");
- break;
-
- case LOG_WARNING:
- rsIcon = IDI_WARNING;
- ppd.colorBack = DEFAULT_LOG1_BACK_COLORS;
- ppd.colorText = DEFAULT_LOG1_TEXT_COLORS;
- mir_strcat(szPrefix, "1");
- break;
-
- case LOG_ERROR:
- rsIcon = IDI_ERROR;
- ppd.colorBack = DEFAULT_LOG2_BACK_COLORS;
- ppd.colorText = DEFAULT_LOG2_TEXT_COLORS;
- mir_strcat(szPrefix, "2");
- break;
-
- case LOG_FATAL:
- rsIcon = IDI_ERROR;
- ppd.colorBack = DEFAULT_LOG3_BACK_COLORS;
- ppd.colorText = DEFAULT_LOG3_TEXT_COLORS;
- mir_strcat(szPrefix, "3");
- break;
-
- case POPTYPE_SPAM:
- rsIcon = IDI_WARNING;
- ppd.colorBack = DEFAULT_SPAM_BACK_COLORS;
- ppd.colorText = DEFAULT_SPAM_TEXT_COLORS;
- mir_strcat(szPrefix, "Spam");
- break;
-
- default:
- return -1;
- }
-
- if (!getByte("PopupsSysIcons", DEFAULT_POPUPS_SYS_ICONS))
- ppd.lchIcon = IcoLib_GetIconByHandle(m_hProtoIcon);
- else
- ppd.lchIcon = (HICON)LoadImageW(nullptr, rsIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
-
- if (getByte("PopupsWinColors", DEFAULT_POPUPS_WIN_COLORS)) {
- ppd.colorText = GetSysColor(COLOR_WINDOWTEXT);
- ppd.colorBack = GetSysColor(COLOR_WINDOW);
- }
- else {
- if (getByte("PopupsDefColors", DEFAULT_POPUPS_DEF_COLORS)) {
- ppd.colorText = NULL;
- ppd.colorBack = NULL;
- }
- else {
- mir_strcpy(szSetting, szPrefix);
- mir_strcat(szSetting, "TextColor");
- ppd.colorText = getDword(szSetting, ppd.colorText);
- mir_strcpy(szSetting, szPrefix);
- mir_strcat(szSetting, "BackColor");
- ppd.colorBack = getDword(szSetting, ppd.colorBack);
- }
- }
- mir_strcpy(szSetting, szPrefix);
- mir_strcat(szSetting, "Timeout");
- ppd.iSeconds = getDword(szSetting, ppd.iSeconds);
-
- char str[4096];
- make_unicode_string_static(ICQTranslateUtfStatic(szTitle, str, sizeof(str)), ppd.lpwzContactName, MAX_CONTACTNAME);
- make_unicode_string_static(ICQTranslateUtfStatic(szMsg, str, sizeof(str)), ppd.lpwzText, MAX_SECONDLINE);
- ppd.lchContact = hContact;
- ppd.PluginWindowProc = nullptr;
- ppd.PluginData = nullptr;
- return PUAddPopupT(&ppd);
- }
- return -1; // Failure
-}
diff --git a/protocols/IcqOscarJ/src/icq_popups.h b/protocols/IcqOscarJ/src/icq_popups.h
deleted file mode 100644
index 319ffb6529..0000000000
--- a/protocols/IcqOscarJ/src/icq_popups.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-//
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Headers for Popup Plugin support
-//
-// -----------------------------------------------------------------------------
-#ifndef __ICQ_POPUPS_H
-#define __ICQ_POPUPS_H
-
-
-#define POPTYPE_SPAM 254 // this is for spambots
-
-int ModuleLoad(WPARAM, LPARAM);
-void InitPopupOpts(WPARAM wParam);
-
-
-#endif /* __ICQ_POPUPS_H */
diff --git a/protocols/IcqOscarJ/src/icq_proto.cpp b/protocols/IcqOscarJ/src/icq_proto.cpp
deleted file mode 100644
index bc33862ae0..0000000000
--- a/protocols/IcqOscarJ/src/icq_proto.cpp
+++ /dev/null
@@ -1,1819 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera, George Hazan
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Protocol Interface Implementation
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-#include "m_icolib.h"
-
-#pragma warning(disable:4355)
-
-static int CompareConns(const directconnect *p1, const directconnect *p2)
-{
- if (p1 < p2)
- return -1;
-
- return (p1 == p2) ? 0 : 1;
-}
-
-static int CompareCookies(const icq_cookie_info *p1, const icq_cookie_info *p2)
-{
- if (p1->dwCookie < p2->dwCookie)
- return -1;
-
- return (p1->dwCookie == p2->dwCookie) ? 0 : 1;
-}
-
-static int CompareFT(const filetransfer *p1, const filetransfer *p2)
-{
- if (p1->dwCookie < p2->dwCookie)
- return -1;
-
- return (p1->dwCookie == p2->dwCookie) ? 0 : 1;
-}
-
-static int CompareContactsCache(const icq_contacts_cache *p1, const icq_contacts_cache *p2)
-{
- if (p1->dwUin < p2->dwUin)
- return -1;
-
- if (p1->dwUin > p2->dwUin)
- return 1;
-
- return mir_strcmpi(p1->szUid, p2->szUid);
-}
-
-CIcqProto::CIcqProto(const char* aProtoName, const wchar_t* aUserName) :
- PROTO<CIcqProto>(aProtoName, aUserName),
- cookies(10, CompareCookies),
- directConns(10, CompareConns),
- expectedFileRecvs(10, CompareFT),
- contactsCache(10, CompareContactsCache),
- CustomCapList(1),
- cheekySearchId(-1),
- m_arAvatars(5),
- m_arFileTransfers(1)
-{
- debugLogA("Setting protocol/module name to '%s'", m_szModuleName);
-
- // Initialize server lists
- HookProtoEvent(ME_CLIST_GROUPCHANGE, &CIcqProto::ServListCListGroupChange);
- HookProtoEvent(ME_DB_CONTACT_SETTINGCHANGED, &CIcqProto::ServListDbSettingChanged);
-
- // Initialize status message struct
- memset(&m_modeMsgs, 0, sizeof(icq_mode_messages));
-
- m_modeMsgsEvent = CreateProtoEvent(ME_ICQ_STATUSMSGREQ);
-
- // Initialize cookies
- wCookieSeq = 2;
-
- // Initialize temporary DB settings
- db_set_resident(m_szModuleName, "TemporaryVisible");
- db_set_resident(m_szModuleName, "TickTS");
- db_set_resident(m_szModuleName, "IdleTS");
- db_set_resident(m_szModuleName, "AwayTS");
- db_set_resident(m_szModuleName, "LogonTS");
- db_set_resident(m_szModuleName, "DCStatus");
- db_set_resident(m_szModuleName, "CapBuf"); //capabilities bufer
- db_set_resident(m_szModuleName, DBSETTING_STATUS_NOTE_TIME);
- db_set_resident(m_szModuleName, DBSETTING_STATUS_MOOD);
-
- // Setup services
- CreateProtoService(PS_CREATEACCMGRUI, &CIcqProto::OnCreateAccMgrUI);
- CreateProtoService(MS_ICQ_SENDSMS, &CIcqProto::SendSms);
- CreateProtoService(PS_SETMYNICKNAME, &CIcqProto::SetNickName);
-
- CreateProtoService(PS_GETMYAWAYMSG, &CIcqProto::GetMyAwayMsg);
-
- CreateProtoService(PS_GETINFOSETTING, &CIcqProto::GetInfoSetting);
-
- CreateProtoService(PSS_ADDED, &CIcqProto::SendYouWereAdded);
-
- // ChangeInfo API
- CreateProtoService(PS_CHANGEINFOEX, &CIcqProto::ChangeInfoEx);
-
- // Avatar API
- CreateProtoService(PS_GETAVATARINFO, &CIcqProto::GetAvatarInfo);
- CreateProtoService(PS_GETAVATARCAPS, &CIcqProto::GetAvatarCaps);
- CreateProtoService(PS_GETMYAVATAR, &CIcqProto::GetMyAvatar);
- CreateProtoService(PS_SETMYAVATAR, &CIcqProto::SetMyAvatar);
-
- // Custom Status API
- CreateProtoService(PS_SETCUSTOMSTATUSEX, &CIcqProto::SetXStatusEx);
- CreateProtoService(PS_GETCUSTOMSTATUSEX, &CIcqProto::GetXStatusEx);
- CreateProtoService(PS_GETCUSTOMSTATUSICON, &CIcqProto::GetXStatusIcon);
- CreateProtoService(PS_GETADVANCEDSTATUSICON, &CIcqProto::RequestAdvStatusIconIdx);
- CreateProtoService(PS_ICQ_REQUESTCUSTOMSTATUS, &CIcqProto::RequestXStatusDetails);
-
- CreateProtoService(MS_ICQ_ADDSERVCONTACT, &CIcqProto::AddServerContact);
-
- CreateProtoService(PS_MENU_REQAUTH, &CIcqProto::RequestAuthorization);
- CreateProtoService(PS_MENU_GRANTAUTH, &CIcqProto::GrantAuthorization);
- CreateProtoService(PS_MENU_REVOKEAUTH, &CIcqProto::RevokeAuthorization);
-
- CreateProtoService(MS_XSTATUS_SHOWDETAILS, &CIcqProto::ShowXStatusDetails);
-
- // Custom caps
- CreateProtoService(PS_ICQ_ADDCAPABILITY, &CIcqProto::IcqAddCapability);
- CreateProtoService(PS_ICQ_CHECKCAPABILITY, &CIcqProto::IcqCheckCapability);
-
- // Reset a bunch of session specific settings
- UpdateGlobalSettings();
- ResetSettingsOnLoad();
-
- // Initialize Contacts Cache
- InitContactsCache();
-
- HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &CIcqProto::OnPreBuildStatusMenu);
- HookProtoEvent(ME_OPT_INITIALISE, &CIcqProto::OnOptionsInit);
-
- // Register netlib users
- wchar_t szBuffer[MAX_PATH + 64];
- mir_snwprintf(szBuffer, TranslateT("%s server connection"), m_tszUserName);
-
- NETLIBUSER nlu = {};
- nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_UNICODE;
- nlu.szDescriptiveName.w = szBuffer;
- nlu.szSettingsModule = m_szModuleName;
- nlu.szHttpGatewayHello = "http://http.proxy.icq.com/hello";
- nlu.szHttpGatewayUserAgent = NETLIB_USER_AGENT;
- nlu.pfnHttpGatewayInit = icq_httpGatewayInit;
- nlu.pfnHttpGatewayBegin = icq_httpGatewayBegin;
- nlu.pfnHttpGatewayWrapSend = icq_httpGatewayWrapSend;
- nlu.pfnHttpGatewayUnwrapRecv = icq_httpGatewayUnwrapRecv;
- m_hNetlibUser = Netlib_RegisterUser(&nlu);
-
- char szP2PModuleName[MAX_PATH];
- mir_snprintf(szP2PModuleName, "%sP2P", m_szModuleName);
- mir_snwprintf(szBuffer, TranslateT("%s client-to-client connections"), m_tszUserName);
- nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_UNICODE;
- nlu.szDescriptiveName.w = szBuffer;
- nlu.szSettingsModule = szP2PModuleName;
- nlu.minIncomingPorts = 1;
- m_hDirectNetlibUser = Netlib_RegisterUser(&nlu);
-
- // Register custom database events
- DBEVENTTYPEDESCR eventType = { sizeof(eventType) };
- eventType.eventType = ICQEVENTTYPE_MISSEDMESSAGE;
- eventType.module = m_szModuleName;
- eventType.descr = "Missed message notifications";
- eventType.textService = ICQ_DB_GETEVENTTEXT_MISSEDMESSAGE;
- eventType.flags = DETF_HISTORY | DETF_MSGWINDOW;
- // for now keep default "message" icon
- DbEvent_RegisterType(&eventType);
-
- // Protocol instance is ready
- debugLogA("%s: Protocol instance '%s' created.", ICQ_PROTOCOL_NAME, m_szModuleName);
-}
-
-CIcqProto::~CIcqProto()
-{
- m_bXStatusEnabled = 10; // block clist changing
- m_bMoodsEnabled = 10;
-
- // Serv-list update board clean-up
- FlushServerIDs();
- /// TODO: make sure server-list handler thread is not running
- /// TODO: save state of server-list update board to DB
- servlistPendingFlushOperations();
- SAFE_FREE((void**)&servlistQueueList);
-
- // Finalize avatars
- for (auto &it : m_arAvatars)
- delete it;
-
- // NetLib clean-up
- Netlib_CloseHandle(m_hDirectNetlibUser);
- Netlib_CloseHandle(m_hNetlibUser);
-
- // Destroy hookable events
- if (m_modeMsgsEvent)
- DestroyHookableEvent(m_modeMsgsEvent);
-
- // Clean-up remaining protocol instance members
- UninitContactsCache();
-
- SAFE_FREE(&m_modeMsgs.szOnline);
- SAFE_FREE(&m_modeMsgs.szAway);
- SAFE_FREE(&m_modeMsgs.szNa);
- SAFE_FREE(&m_modeMsgs.szOccupied);
- SAFE_FREE(&m_modeMsgs.szDnd);
- SAFE_FREE(&m_modeMsgs.szFfc);
-
- debugLogA("%s: Protocol instance '%s' destroyed.", ICQ_PROTOCOL_NAME, m_szModuleName);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// OnModulesLoadedEx - performs hook registration
-
-void CIcqProto::OnModulesLoaded()
-{
- char pszP2PName[MAX_PATH];
- char pszGroupsName[MAX_PATH];
- char pszSrvGroupsName[MAX_PATH];
- char* modules[5] = { nullptr, nullptr, nullptr, nullptr, nullptr };
-
- mir_snprintf(pszP2PName, "%sP2P", m_szModuleName);
- mir_snprintf(pszGroupsName, "%sGroups", m_szModuleName);
- mir_snprintf(pszSrvGroupsName, "%sSrvGroups", m_szModuleName);
- modules[0] = m_szModuleName;
- modules[1] = pszP2PName;
- modules[2] = pszGroupsName;
- modules[3] = pszSrvGroupsName;
- CallService("DBEditorpp/RegisterModule", (WPARAM)modules, (LPARAM)4);
-
- // Startup Auto Info-Update thread
- icq_InitInfoUpdate();
-
- HookProtoEvent(ME_USERINFO_INITIALISE, &CIcqProto::OnUserInfoInit);
- HookProtoEvent(ME_IDLE_CHANGED, &CIcqProto::OnIdleChanged);
-
- // Init extra optional modules
- ModuleLoad(0, 0);
- InitXStatusItems(FALSE);
-
- for (auto &hContact : AccContacts()) {
- DWORD bXStatus = getContactXStatus(hContact);
- if (bXStatus > 0)
- setContactExtraIcon(hContact, bXStatus);
- }
-}
-
-void CIcqProto::OnShutdown()
-{
- // signal info update thread to stop
- icq_InfoUpdateCleanup();
-
- // Make sure all connections are closed
- CloseContactDirectConns(NULL);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_AddToList - adds a contact to the contact list
-
-MCONTACT CIcqProto::AddToList(int flags, PROTOSEARCHRESULT *psr)
-{
- if (psr == nullptr) return 0;
-
- char szUid[MAX_PATH];
- if (psr->cbSize == sizeof(ICQSEARCHRESULT)) {
- ICQSEARCHRESULT *isr = (ICQSEARCHRESULT*)psr;
- if (isr->uin)
- return AddToListByUIN(isr->uin, flags);
-
- // aim contact
- if (isr->hdr.flags & PSR_UNICODE)
- unicode_to_ansi_static((WCHAR*)isr->hdr.id.w, szUid, MAX_PATH);
- else
- null_strcpy(szUid, (char*)isr->hdr.id.w, MAX_PATH);
-
- return (szUid[0] == 0) ? 0 : AddToListByUID(szUid, flags);
- }
-
- if (psr->flags & PSR_UNICODE)
- unicode_to_ansi_static((WCHAR*)psr->id.w, szUid, MAX_PATH);
- else
- null_strcpy(szUid, (char*)psr->id.w, MAX_PATH);
-
- if (szUid[0] == 0)
- return 0;
- if (IsStringUIN(szUid))
- return AddToListByUIN(atoi(szUid), flags);
- return AddToListByUID(szUid, flags);
-}
-
-MCONTACT CIcqProto::AddToListByEvent(int flags, int iContact, MEVENT hDbEvent)
-{
- DWORD uin = 0;
- uid_str uid = { 0 };
-
- DBEVENTINFO dbei = {};
- if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == -1)
- return 0;
-
- dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob + 1);
- dbei.pBlob[dbei.cbBlob] = '\0';
-
- if (db_event_get(hDbEvent, &dbei))
- return 0; // failed to get event
-
- if (mir_strcmp(dbei.szModule, m_szModuleName))
- return 0; // this event is not ours
-
- switch (dbei.eventType) {
- case EVENTTYPE_CONTACTS:
- {
- char *pbOffset = (char*)dbei.pBlob;
- char *pbEnd = pbOffset + dbei.cbBlob;
- for (int i = 0; i <= iContact; i++) {
- pbOffset += mir_strlen(pbOffset) + 1; // Nick
- if (pbOffset >= pbEnd) break;
- if (i == iContact) { // we found the contact, get uid
- if (IsStringUIN((char*)pbOffset))
- uin = atoi((char*)pbOffset);
- else {
- uin = 0;
- mir_strcpy(uid, (char*)pbOffset);
- }
- }
- pbOffset += mir_strlen(pbOffset) + 1; // Uin
- if (pbOffset >= pbEnd) break;
- }
- }
- break;
-
- case EVENTTYPE_AUTHREQUEST:
- case EVENTTYPE_ADDED:
- if (!getContactUid(DbGetAuthEventContact(&dbei), &uin, &uid))
- break;
-
- default:
- return 0;
- }
-
- if (uin != 0)
- return AddToListByUIN(uin, flags); // Success
-
- // add aim contact
- if (mir_strlen(uid))
- return AddToListByUID(uid, flags); // Success
-
- return NULL; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_AuthAllow - processes the successful authorization
-
-int CIcqProto::Authorize(MEVENT hDbEvent)
-{
- if (icqOnline() && hDbEvent) {
- MCONTACT hContact = HContactFromAuthEvent(hDbEvent);
- if (hContact == INVALID_CONTACT_ID)
- return 1;
-
- DWORD uin;
- uid_str uid;
- if (getContactUid(hContact, &uin, &uid))
- return 1;
-
- icq_sendAuthResponseServ(uin, uid, 1, L"");
-
- delSetting(hContact, "Grant");
-
- return 0; // Success
- }
-
- return 1; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_AuthDeny - handles the unsuccessful authorization
-
-int CIcqProto::AuthDeny(MEVENT hDbEvent, const wchar_t* szReason)
-{
- if (icqOnline() && hDbEvent) {
- MCONTACT hContact = HContactFromAuthEvent(hDbEvent);
- if (hContact == INVALID_CONTACT_ID)
- return 1;
-
- DWORD uin;
- uid_str uid;
- if (getContactUid(hContact, &uin, &uid))
- return 1;
-
- icq_sendAuthResponseServ(uin, uid, 0, szReason);
-
- if (db_get_b(hContact, "CList", "NotOnList", 0))
- db_delete_contact(hContact);
-
- return 0; // Success
- }
-
- return 1; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PSR_AUTH
-
-int CIcqProto::AuthRecv(MCONTACT hContact, PROTORECVEVENT* pre)
-{
- setContactHidden(hContact, 0);
- ICQAddRecvEvent(NULL, EVENTTYPE_AUTHREQUEST, pre, pre->lParam, (PBYTE)pre->szMessage, 0);
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PSS_AUTHREQUEST
-
-int CIcqProto::AuthRequest(MCONTACT hContact, const wchar_t* szMessage)
-{
- if (!icqOnline())
- return 1;
-
- if (hContact) {
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return 1; // Invalid contact
-
- if (dwUin) {
- char *utf = make_utf8_string(szMessage);
- icq_sendAuthReqServ(dwUin, szUid, utf);
- SAFE_FREE(&utf);
- return 0; // Success
- }
- }
-
- return 1; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_FileAllow - starts a file transfer
-
-HANDLE CIcqProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t* szPath)
-{
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return nullptr; // Invalid contact
-
- if (icqOnline() && hContact && szPath && hTransfer) { // approve old fashioned file transfer
- basic_filetransfer *bft = (basic_filetransfer *)hTransfer;
-
- if (!IsValidFileTransfer(bft))
- return nullptr; // Invalid transfer
-
- if (dwUin && bft->ft_magic == FT_MAGIC_ICQ) {
- filetransfer *ft = (filetransfer *)hTransfer;
- ft->szSavePath = make_utf8_string(szPath);
- {
- mir_cslock l(expectedFileRecvMutex);
- expectedFileRecvs.insert(ft);
- }
-
- // Was request received thru DC and have we a open DC, send through that
- if (ft->bDC && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0))
- icq_sendFileAcceptDirect(hContact, ft);
- else
- icq_sendFileAcceptServ(dwUin, ft, 0);
-
- return hTransfer; // Success
- }
- else if (bft->ft_magic == FT_MAGIC_OSCAR) { // approve oscar file transfer
- return oftFileAllow(hContact, hTransfer, szPath);
- }
- }
-
- return nullptr; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_FileCancel - cancels a file transfer
-
-int CIcqProto::FileCancel(MCONTACT hContact, HANDLE hTransfer)
-{
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return 1; // Invalid contact
-
- if (hContact && hTransfer) {
- basic_filetransfer *ft = (basic_filetransfer *)hTransfer;
-
- if (!IsValidFileTransfer(ft))
- return 1; // Invalid transfer
-
- if (dwUin && ft->ft_magic == FT_MAGIC_ICQ) { // cancel old fashioned file transfer
- icq_CancelFileTransfer((filetransfer*)hTransfer);
- return 0; // Success
- }
- if (ft->ft_magic == FT_MAGIC_OSCAR) { // cancel oscar file transfer
- return oftFileCancel(hContact, hTransfer);
- }
- }
-
- return 1; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_FileDeny - denies a file transfer
-
-int CIcqProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t* szReason)
-{
- int nReturnValue = 1;
- basic_filetransfer *bft = (basic_filetransfer*)hTransfer;
-
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return 1; // Invalid contact
-
- if (icqOnline() && hTransfer && hContact) {
- if (!IsValidFileTransfer((basic_filetransfer*)hTransfer))
- return 1; // Invalid transfer
-
- if (dwUin && bft->ft_magic == FT_MAGIC_ICQ) { // deny old fashioned file transfer
- filetransfer *ft = (filetransfer*)hTransfer;
- char *szReasonUtf = make_utf8_string(szReason);
- // Was request received thru DC and have we a open DC, send through that
- if (ft->bDC && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0))
- icq_sendFileDenyDirect(hContact, ft, szReasonUtf);
- else
- icq_sendFileDenyServ(dwUin, ft, szReasonUtf, 0);
- SAFE_FREE(&szReasonUtf);
-
- nReturnValue = 0; // Success
- }
- else if (bft->ft_magic == FT_MAGIC_OSCAR) { // deny oscar file transfer
- return oftFileDeny(hContact, hTransfer, szReason);
- }
- }
- // Release possible orphan structure
- SafeReleaseFileTransfer(&bft);
-
- return nReturnValue;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_FileResume - processes file renaming etc
-
-int CIcqProto::FileResume(HANDLE hTransfer, int* action, const wchar_t** szFilename)
-{
- if (icqOnline() && hTransfer) {
- basic_filetransfer *ft = (basic_filetransfer *)hTransfer;
-
- if (!IsValidFileTransfer(ft))
- return 1; // Invalid transfer
-
- if (ft->ft_magic == FT_MAGIC_ICQ) {
- char *szFileNameUtf = make_utf8_string(*szFilename);
- icq_sendFileResume((filetransfer *)hTransfer, *action, szFileNameUtf);
- SAFE_FREE(&szFileNameUtf);
- }
- else if (ft->ft_magic == FT_MAGIC_OSCAR) {
- oftFileResume((oscar_filetransfer *)hTransfer, *action, *szFilename);
- }
- else
- return 1; // Failure
-
- return 0; // Success
- }
-
- return 1; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// GetCaps - return protocol capabilities bits
-
-INT_PTR CIcqProto::GetCaps(int type, MCONTACT hContact)
-{
- INT_PTR nReturn = 0;
-
- switch (type) {
-
- case PFLAGNUM_1:
- nReturn = PF1_IM | PF1_URL | PF1_AUTHREQ | PF1_BASICSEARCH | PF1_ADDSEARCHRES |
- PF1_VISLIST | PF1_INVISLIST | PF1_MODEMSG | PF1_FILE | PF1_EXTSEARCH |
- PF1_EXTSEARCHUI | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME |
- PF1_ADDED | PF1_CONTACT;
-
- if (m_bSsiEnabled && getByte("ServerAddRemove", DEFAULT_SS_ADDSERVER))
- nReturn |= PF1_SERVERCLIST;
- break;
-
- case PFLAGNUM_2:
- return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND |
- PF2_FREECHAT | PF2_INVISIBLE | PF2_ONTHEPHONE;
-
- case PFLAGNUM_3:
- return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND |
- PF2_FREECHAT | PF2_INVISIBLE;
-
- case PFLAGNUM_4:
- nReturn = PF4_SUPPORTIDLE | PF4_IMSENDOFFLINE | PF4_INFOSETTINGSVC | PF4_SUPPORTTYPING;
- if (m_bAvatarsEnabled)
- nReturn |= PF4_AVATARS;
- break;
-
- case PFLAGNUM_5:
- return PF2_FREECHAT | PF2_ONTHEPHONE;
-
- case PFLAG_UNIQUEIDTEXT:
- return (INT_PTR)Translate("User ID");
-
- case PFLAG_MAXLENOFMESSAGE:
- return MAX_MESSAGESNACSIZE - 102;
-
- case PFLAG_MAXCONTACTSPERPACKET:
- if (hContact == 0)
- return MAX_CONTACTSSEND;
-
- // determine per contact
- BYTE bClientId = getByte(hContact, "ClientID", CLID_GENERIC);
-
- if (bClientId == CLID_MIRANDA) {
- if (CheckContactCapabilities(hContact, CAPF_CONTACTS) && getContactStatus(hContact) != ID_STATUS_OFFLINE)
- return 0x100; // limited only by packet size
- return MAX_CONTACTSSEND;
- }
- else if (bClientId == CLID_ICQ6) {
- // crapy ICQ6 cannot handle multiple contacts in the transfer
- return CheckContactCapabilities(hContact, CAPF_CONTACTS) != 0;
- }
- return MAX_CONTACTSSEND;
- }
-
- return nReturn;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// GetInfo - retrieves a contact info
-
-int CIcqProto::GetInfo(MCONTACT hContact, int infoType)
-{
- if (icqOnline()) {
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return 1; // Invalid contact
-
- DWORD dwCookie;
- if (dwUin)
- dwCookie = icq_sendGetInfoServ(hContact, dwUin, (infoType & SGIF_ONOPEN) != 0);
- else // TODO: this needs something better
- dwCookie = icq_sendGetAimProfileServ(hContact, szUid);
-
- return (dwCookie) ? 0 : 1;
- }
-
- return 1; // Failure
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// SearchBasic - searches the contact by UID
-
-void CIcqProto::CheekySearchThread(void*)
-{
- char szUin[UINMAXLEN];
- ICQSEARCHRESULT isr = { 0 };
- isr.hdr.cbSize = sizeof(isr);
-
- Thread_SetName("ICQ: CheekySearchThread");
-
- if (cheekySearchUin) {
- _itoa(cheekySearchUin, szUin, 10);
- isr.hdr.id.w = (wchar_t*)szUin;
- }
- else {
- isr.hdr.id.w = (wchar_t*)cheekySearchUid;
- }
- isr.uin = cheekySearchUin;
-
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)cheekySearchId, (LPARAM)&isr);
- ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)cheekySearchId, 0);
- cheekySearchId = -1;
-}
-
-
-HANDLE CIcqProto::SearchBasic(const wchar_t *pszSearch)
-{
- if (mir_wstrlen(pszSearch) == 0)
- return nullptr;
-
- char pszUIN[255];
- int nHandle = 0;
- size_t i, j;
-
- for (i = j = 0; (i < mir_wstrlen(pszSearch)) && (j < 255); i++) { // we remove spaces and slashes
- if ((pszSearch[i] != 0x20) && (pszSearch[i] != '-')) {
- if (pszSearch[i] >= 0x80) continue;
- pszUIN[j] = pszSearch[i];
- j++;
- }
- }
- pszUIN[j] = 0;
-
- if (mir_strlen(pszUIN)) {
- DWORD dwUin;
- if (IsStringUIN(pszUIN))
- dwUin = atoi(pszUIN);
- else
- dwUin = 0;
-
- // Cheeky instant UIN search
- if (!dwUin || GetKeyState(VK_CONTROL) & 0x8000) {
- cheekySearchId = GenerateCookie(0);
- cheekySearchUin = dwUin;
- cheekySearchUid = null_strdup(pszUIN);
- ForkThread(&CIcqProto::CheekySearchThread, nullptr); // The caller needs to get this return value before the results
- nHandle = cheekySearchId;
- }
- else if (icqOnline()) {
- nHandle = SearchByUin(dwUin);
- }
-
- // Success
- return (HANDLE)nHandle;
- }
-
- // Failure
- return nullptr;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// SearchByEmail - searches the contact by its e-mail
-
-HANDLE CIcqProto::SearchByEmail(const wchar_t *email)
-{
- if (email && icqOnline() && mir_wstrlen(email) > 0) {
- char *szEmail = unicode_to_ansi(email);
-
- // Success
- DWORD dwSearchId = SearchByMail(szEmail);
- DWORD dwSecId = (dwSearchId == 0) ? icq_searchAimByEmail(szEmail, dwSearchId) : 0;
-
- SAFE_FREE(&szEmail);
-
- if (dwSearchId)
- return (HANDLE)dwSearchId;
- else
- return (HANDLE)dwSecId;
- }
-
- return nullptr; // Failure
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_SearchByName - searches the contact by its first or last name, or by a nickname
-
-HANDLE CIcqProto::SearchByName(const wchar_t *nick, const wchar_t *firstName, const wchar_t *lastName)
-{
- if (icqOnline()) {
- if (nick || firstName || lastName) {
- char *nickUtf = make_utf8_string(nick);
- char *firstNameUtf = make_utf8_string(firstName);
- char *lastNameUtf = make_utf8_string(lastName);
-
- // Success
- HANDLE dwCookie = (HANDLE)SearchByNames(nickUtf, firstNameUtf, lastNameUtf, 0);
-
- SAFE_FREE(&nickUtf);
- SAFE_FREE(&firstNameUtf);
- SAFE_FREE(&lastNameUtf);
-
- return dwCookie;
- }
- }
-
- return nullptr; // Failure
-}
-
-
-HWND CIcqProto::CreateExtendedSearchUI(HWND parent)
-{
- if (parent && g_plugin.getInst())
- return CreateDialog(g_plugin.getInst(), MAKEINTRESOURCE(IDD_ICQADVANCEDSEARCH), parent, AdvancedSearchDlgProc);
-
- return nullptr; // Failure
-}
-
-HWND CIcqProto::SearchAdvanced(HWND hwndDlg)
-{
- if (icqOnline() && IsWindow(hwndDlg)) {
- size_t nDataLen;
- BYTE* bySearchData;
-
- if (bySearchData = createAdvancedSearchStructure(hwndDlg, &nDataLen)) {
- int result = icq_sendAdvancedSearchServ(bySearchData, nDataLen);
- SAFE_FREE((void**)&bySearchData);
- return (HWND)result; // Success
- }
- }
-
- return nullptr; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// RecvContacts
-
-int CIcqProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre)
-{
- ICQSEARCHRESULT **isrList = (ICQSEARCHRESULT**)pre->szMessage;
- int i;
- size_t cbBlob = 0;
- DWORD flags = DBEF_UTF;
-
- for (i = 0; i < pre->lParam; i++) {
- cbBlob += mir_strlen((char*)isrList[i]->hdr.nick.w) + 2; // both trailing zeros
- if (isrList[i]->uin)
- cbBlob += getUINLen(isrList[i]->uin);
- else
- cbBlob += mir_strlen((char*)isrList[i]->hdr.id.w);
- }
- PBYTE pBlob = (PBYTE)_alloca(cbBlob), pCurBlob;
- for (i = 0, pCurBlob = pBlob; i < pre->lParam; i++) {
- mir_strcpy((char*)pCurBlob, (char*)isrList[i]->hdr.nick.w);
- pCurBlob += mir_strlen((char*)pCurBlob) + 1;
- if (isrList[i]->uin) {
- char szUin[UINMAXLEN];
- _itoa(isrList[i]->uin, szUin, 10);
- mir_strcpy((char*)pCurBlob, szUin);
- }
- else // aim contact
- mir_strcpy((char*)pCurBlob, (char*)isrList[i]->hdr.id.w);
-
- pCurBlob += mir_strlen((char*)pCurBlob) + 1;
- }
-
- ICQAddRecvEvent(hContact, EVENTTYPE_CONTACTS, pre, cbBlob, pBlob, flags);
- return 0;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// RecvMsg
-
-MEVENT CIcqProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT* pre)
-{
- size_t cbBlob = mir_strlen(pre->szMessage) + 1;
- ICQAddRecvEvent(hContact, EVENTTYPE_MESSAGE, pre, cbBlob, (PBYTE)pre->szMessage, DBEF_UTF);
-
- // stop contact from typing - some clients do not sent stop notify
- if (CheckContactCapabilities(hContact, CAPF_TYPING))
- CallService(MS_PROTO_CONTACTISTYPING, hContact, PROTOTYPE_CONTACTTYPING_OFF);
-
- return 0;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// SendContacts
-
-int CIcqProto::SendContacts(MCONTACT hContact, int, int nContacts, MCONTACT *hContactsList)
-{
- if (hContact && hContactsList) {
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid)) // Invalid contact
- return ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "The receiver has an invalid user ID.");
-
- WORD wRecipientStatus = getContactStatus(hContact);
-
- // Failures
- DWORD dwCookie;
- if (!icqOnline())
- dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "You cannot send messages when you are offline.");
- else if (!hContactsList || (nContacts < 1) || (nContacts > MAX_CONTACTSSEND))
- dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "Bad data (internal error #1)");
- else { // OK
- if (CheckContactCapabilities(hContact, CAPF_CONTACTS) && wRecipientStatus != ID_STATUS_OFFLINE) { // Use the new format if possible
- struct icq_contactsend_s* contacts = nullptr;
-
- // Format the data part and the names part
- // This is kinda messy, but there is no simple way to do it. First
- // we need to calculate the length of the packet.
- contacts = (struct icq_contactsend_s*)_alloca(sizeof(struct icq_contactsend_s)*nContacts);
- memset(contacts, 0, (sizeof(struct icq_contactsend_s) * nContacts));
-
- size_t nDataLen = 0, nNamesLen = 0;
- int i;
- for (i = 0; i < nContacts; i++) {
- uid_str szContactUid;
-
- if (!IsICQContact(hContactsList[i]))
- break; // Abort if a non icq contact is found
- if (getContactUid(hContactsList[i], &contacts[i].uin, &szContactUid))
- break; // Abort if invalid contact
- contacts[i].uid = contacts[i].uin ? nullptr : null_strdup(szContactUid);
- contacts[i].szNick = NickFromHandleUtf(hContactsList[i]);
- nDataLen += getUIDLen(contacts[i].uin, contacts[i].uid) + 4;
- nNamesLen += mir_strlen(contacts[i].szNick) + 8;
- }
-
- if (i == nContacts) {
- debugLogA("Sending contacts to %s.", strUID(dwUin, szUid));
-
- // Do not calculate the exact size of the data packet - only the maximal size (easier)
- // Sumarize size of group information
- // - we do not utilize the full power of the protocol and send all contacts with group "General"
- // just like ICQ6 does
- nDataLen += 9;
- nNamesLen += 9;
-
- // Create data structures
- icq_packet mData, mNames;
- mData.wPlace = 0;
- mData.pData = (LPBYTE)SAFE_MALLOC(nDataLen);
- mData.wLen = WORD(nDataLen);
- mNames.wPlace = 0;
- mNames.pData = (LPBYTE)SAFE_MALLOC(nNamesLen);
-
- // pack Group Name
- packWord(&mData, 7);
- packBuffer(&mData, (LPBYTE)"General", 7);
- packWord(&mNames, 7);
- packBuffer(&mNames, (LPBYTE)"General", 7);
-
- // all contacts in one group
- packWord(&mData, WORD(nContacts));
- packWord(&mNames, WORD(nContacts));
- for (i = 0; i < nContacts; i++) {
- uid_str szContactUid;
- if (contacts[i].uin)
- strUID(contacts[i].uin, szContactUid);
- else
- mir_strcpy(szContactUid, contacts[i].uid);
-
- // prepare UID
- size_t wLen = mir_strlen(szContactUid);
- packWord(&mData, WORD(wLen));
- packBuffer(&mData, (LPBYTE)szContactUid, wLen);
-
- // prepare Nick
- wLen = mir_strlen(contacts[i].szNick);
- packWord(&mNames, WORD(wLen + 4));
- packTLV(&mNames, 0x01, wLen, (LPBYTE)contacts[i].szNick);
- }
-
- // Cleanup temporary list
- for (i = 0; i < nContacts; i++) {
- SAFE_FREE(&contacts[i].szNick);
- SAFE_FREE(&contacts[i].uid);
- }
-
- // Rate check
- if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_LIMIT)) { // rate is too high, the message will not go thru...
- SAFE_FREE((void**)&mData.pData);
- SAFE_FREE((void**)&mNames.pData);
-
- return ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "The message could not be delivered. You are sending too fast. Wait a while and try again.");
- }
-
- // Set up the ack type
- cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_CONTACTS, hContact, dwUin, FALSE);
-
- // AIM clients do not send acknowledgement
- if (!dwUin && pCookieData->nAckType == ACKTYPE_CLIENT)
- pCookieData->nAckType = ACKTYPE_SERVER;
- // Send the message
- dwCookie = icq_SendChannel2Contacts(dwUin, szUid, hContact, (char*)mData.pData, mData.wPlace, (char*)mNames.pData, mNames.wPlace, pCookieData);
-
- // This will stop the message dialog from waiting for the real message delivery ack
- if (pCookieData->nAckType == ACKTYPE_NONE) {
- SendProtoAck(hContact, dwCookie, ACKRESULT_SUCCESS, ACKTYPE_CONTACTS, nullptr);
- // We need to free this here since we will never see the real ack
- // The actual cookie value will still have to be returned to the message dialog though
- ReleaseCookie(dwCookie);
- }
- // Release our buffers
- SAFE_FREE((void**)&mData.pData);
- SAFE_FREE((void**)&mNames.pData);
- }
- else {
- dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "Bad data (internal error #2)");
- }
-
- for (i = 0; i < nContacts; i++) {
- SAFE_FREE(&contacts[i].szNick);
- SAFE_FREE(&contacts[i].uid);
- }
- }
- else if (dwUin) { // old format is only understood by ICQ clients
- char szContactUin[UINMAXLEN];
- char szCount[17];
- struct icq_contactsend_s* contacts = nullptr;
- uid_str szContactUid;
- int i;
-
- // Format the body
- // This is kinda messy, but there is no simple way to do it. First
- // we need to calculate the length of the packet.
- contacts = (struct icq_contactsend_s*)_alloca(sizeof(struct icq_contactsend_s)*nContacts);
- memset(contacts, 0, (sizeof(struct icq_contactsend_s) * nContacts));
- {
- size_t nBodyLength = 0;
- for (i = 0; i < nContacts; i++) {
- if (!IsICQContact(hContactsList[i]))
- break; // Abort if a non icq contact is found
- if (getContactUid(hContactsList[i], &contacts[i].uin, &szContactUid))
- break; // Abort if invalid contact
- contacts[i].uid = contacts[i].uin ? nullptr : null_strdup(szContactUid);
- contacts[i].szNick = NickFromHandle(hContactsList[i]);
- // Compute this contact's length
- nBodyLength += getUIDLen(contacts[i].uin, contacts[i].uid) + 1;
- nBodyLength += mir_strlen(contacts[i].szNick) + 1;
- }
-
- if (i == nContacts) {
- debugLogA("Sending contacts to %d.", dwUin);
-
- // Compute count record's length
- _itoa(nContacts, szCount, 10);
- nBodyLength += mir_strlen(szCount) + 1;
-
- // Finally we need to copy the contact data into the packet body
- char *pBody, *pBuffer = pBody = (char *)SAFE_MALLOC(nBodyLength);
- null_strcpy(pBuffer, szCount, nBodyLength - 1);
- pBuffer += mir_strlen(pBuffer);
- *pBuffer++ = -2;
- for (i = 0; i < nContacts; i++) {
- if (contacts[i].uin) {
- _itoa(contacts[i].uin, szContactUin, 10);
- mir_strcpy(pBuffer, szContactUin);
- }
- else
- mir_strcpy(pBuffer, contacts[i].uid);
- pBuffer += mir_strlen(pBuffer);
- *pBuffer++ = -2;
- mir_strcpy(pBuffer, contacts[i].szNick);
- pBuffer += mir_strlen(pBuffer);
- *pBuffer++ = -2;
- }
-
- for (i = 0; i < nContacts; i++) { // release memory
- SAFE_FREE(&contacts[i].szNick);
- SAFE_FREE(&contacts[i].uid);
- }
-
- // Set up the ack type
- cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_CONTACTS, hContact, dwUin, TRUE);
-
- if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) {
- int iRes = icq_SendDirectMessage(hContact, pBody, nBodyLength, pCookieData, nullptr);
- if (iRes) {
- SAFE_FREE((void**)&pBody);
- return iRes; // we succeded, return
- }
- }
-
- // Rate check
- if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_LIMIT)) { // rate is too high, the message will not go thru...
- SAFE_FREE((void**)&pCookieData);
- SAFE_FREE((void**)&pBody);
-
- return ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "The message could not be delivered. You are sending too fast. Wait a while and try again.");
- }
-
- // Select channel and send
- WORD wPriority;
- if (wRecipientStatus == ID_STATUS_ONLINE || wRecipientStatus == ID_STATUS_FREECHAT)
- wPriority = 0x0001;
- else
- wPriority = 0x0021;
-
- dwCookie = icq_SendChannel2Message(dwUin, hContact, pBody, nBodyLength, wPriority, pCookieData, nullptr);
-
- // This will stop the message dialog from waiting for the real message delivery ack
- if (pCookieData->nAckType == ACKTYPE_NONE) {
- SendProtoAck(hContact, dwCookie, ACKRESULT_SUCCESS, ACKTYPE_CONTACTS, nullptr);
- // We need to free this here since we will never see the real ack
- // The actual cookie value will still have to be returned to the message dialog though
- ReleaseCookie(dwCookie);
- }
- SAFE_FREE((void**)&pBody);
- }
- else dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "Bad data (internal error #2)");
- }
- }
- else dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "The reciever does not support receiving of contacts.");
- }
- return dwCookie;
- }
-
- // Exit with Failure
- return 0;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// SendFile - sends a file
-
-HANDLE CIcqProto::SendFile(MCONTACT hContact, const wchar_t* szDescription, wchar_t** ppszFiles)
-{
- if (!icqOnline())
- return nullptr;
-
- if (hContact && szDescription && ppszFiles) {
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return nullptr; // Invalid contact
-
- if (getContactStatus(hContact) != ID_STATUS_OFFLINE) {
- if (CheckContactCapabilities(hContact, CAPF_OSCAR_FILE))
- return oftInitTransfer(hContact, dwUin, szUid, (LPCTSTR*)ppszFiles, szDescription);
-
- if (dwUin) {
- WORD wClientVersion = getWord(hContact, "Version", 7);
-
- if (wClientVersion < 7)
- debugLogA("IcqSendFile() can't send to version %u", wClientVersion);
- else {
- int i;
- filetransfer* ft;
- struct _stat statbuf;
-
- // Initialize filetransfer struct
- ft = CreateFileTransfer(hContact, dwUin, (wClientVersion == 7) ? 7 : 8);
-
- for (ft->dwFileCount = 0; ppszFiles[ft->dwFileCount]; ft->dwFileCount++);
- ft->pszFiles = (char **)SAFE_MALLOC(sizeof(char *)* ft->dwFileCount);
- ft->dwTotalSize = 0;
- for (i = 0; i < (int)ft->dwFileCount; i++) {
- ft->pszFiles[i] = (ppszFiles[i]) ? make_utf8_string(ppszFiles[i]) : nullptr;
-
- if (_wstat(ppszFiles[i], &statbuf))
- debugLogA("IcqSendFile() was passed invalid filename(s)");
- else
- ft->dwTotalSize += statbuf.st_size;
- }
- ft->szDescription = make_utf8_string(szDescription);
- ft->dwTransferSpeed = 100;
- ft->sending = 1;
- ft->fileId = -1;
- ft->iCurrentFile = 0;
- ft->dwCookie = AllocateCookie(CKT_FILE, 0, hContact, ft);
- ft->hConnection = nullptr;
-
- // Send file transfer request
- debugLogA("Init file send");
-
- char *pszFiles, szFiles[64];
- if (ft->dwFileCount == 1) {
- pszFiles = strchr(ft->pszFiles[0], '\\');
- if (pszFiles)
- pszFiles++;
- else
- pszFiles = ft->pszFiles[0];
- }
- else {
- char tmp[64];
- mir_snprintf(szFiles, ICQTranslateUtfStatic("%d Files", tmp, _countof(tmp)), ft->dwFileCount);
- pszFiles = szFiles;
- }
-
- // Send packet
- if (ft->nVersion == 7) {
- if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) {
- int iRes = icq_sendFileSendDirectv7(ft, pszFiles);
- if (iRes) return ft; // Success
- }
- debugLogA("Sending v%u file transfer request through server", 7);
- icq_sendFileSendServv7(ft, pszFiles);
- }
- else {
- if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) {
- int iRes = icq_sendFileSendDirectv8(ft, pszFiles);
- if (iRes)
- return ft; // Success
- }
- debugLogA("Sending v%u file transfer request through server", 8);
- icq_sendFileSendServv8(ft, pszFiles, ACKTYPE_NONE);
- }
-
- return ft; // Success
- }
- }
- }
- }
-
- return nullptr; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_SendMessage - sends a message
-
-int CIcqProto::SendMsg(MCONTACT hContact, int, const char* pszSrc)
-{
- if (hContact == NULL || pszSrc == nullptr)
- return NULL;
-
- DWORD dwCookie;
- char* puszText = (char*)pszSrc;
- int bNeedFreeU = 0;
-
- // Invalid contact
- DWORD dwUin;
- uid_str szUID;
- if (getContactUid(hContact, &dwUin, &szUID))
- return ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "The receiver has an invalid user ID.");
-
- WORD wRecipientStatus = getContactStatus(hContact);
-
- BOOL plain_ascii = IsUSASCII(puszText, mir_strlen(puszText));
- BOOL oldAnsi = plain_ascii || !CheckContactCapabilities(hContact, CAPF_UTF) || !getByte(hContact, "UnicodeSend", 1);
-
- if (m_bTempVisListEnabled && m_iStatus == ID_STATUS_INVISIBLE)
- makeContactTemporaryVisible(hContact); // make us temporarily visible to contact
-
- // Failure scenarios
- if (!icqOnline())
- dwCookie = ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "You cannot send messages when you are offline.");
- else if ((wRecipientStatus == ID_STATUS_OFFLINE) && (mir_strlen(puszText) > 4096))
- dwCookie = ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "Messages to offline contacts must be shorter than 4096 characters.");
- // Looks OK
- else {
- debugLogA("Send %smessage - Message cap is %u", puszText ? "unicode " : "", CheckContactCapabilities(hContact, CAPF_SRV_RELAY));
- debugLogA("Send %smessage - Contact status is %u", puszText ? "unicode " : "", wRecipientStatus);
-
- if (dwUin && m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) { // send thru direct
- char *dc_msg = puszText;
- char *dc_cap = plain_ascii ? NULL : CAP_UTF8MSGS;
- char *szUserAnsi = nullptr;
-
- if (!plain_ascii && oldAnsi) {
- szUserAnsi = ConvertMsgToUserSpecificAnsi(hContact, puszText);
- if (szUserAnsi) {
- dc_msg = szUserAnsi;
- dc_cap = NULL;
- }
- }
-
- // Set up the ack type
- cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_PLAIN, hContact, dwUin, TRUE);
- pCookieData->nAckType = ACKTYPE_CLIENT;
- dwCookie = icq_SendDirectMessage(hContact, dc_msg, mir_strlen(dc_msg), pCookieData, dc_cap);
-
- SAFE_FREE(&szUserAnsi);
- if (dwCookie) // free the buffers if alloced
- return dwCookie; // we succeded, return
-
- // on failure, fallback to send thru server
- }
-
- /// TODO: add support for RTL & user customizable font
- {
- char *mng = MangleXml(puszText, mir_strlen(puszText));
- size_t len = mir_strlen(mng);
- mng = (char*)SAFE_REALLOC(mng, len + 28);
- memmove(mng + 12, mng, len + 1);
- memcpy(mng, "<HTML><BODY>", 12);
- mir_strcat(mng, "</BODY></HTML>");
- puszText = mng;
- bNeedFreeU = 1;
- }
-
- WCHAR *pwszText = plain_ascii ? nullptr : make_unicode_string(puszText);
- if ((plain_ascii ? mir_strlen(puszText) : mir_wstrlen(pwszText) * sizeof(WCHAR)) > MAX_MESSAGESNACSIZE) { // max length check // TLV(2) is currently limited to 0xA00 bytes in online mode
- // only limit to not get disconnected, all other will be handled by error 0x0A
- dwCookie = ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "The message could not be delivered, it is too long.");
-
- // free the buffers if alloced
- SAFE_FREE((void**)&pwszText);
- if (bNeedFreeU) SAFE_FREE(&puszText);
-
- return dwCookie;
- }
- // Rate check
- if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_LIMIT)) { // rate is too high, the message will not go thru...
- dwCookie = ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "The message could not be delivered. You are sending too fast. Wait a while and try again.");
-
- // free the buffers if alloced
- SAFE_FREE((void**)&pwszText);
- if (bNeedFreeU) SAFE_FREE(&puszText);
-
- return dwCookie;
- }
-
- cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_PLAIN, hContact, dwUin, FALSE);
-
- if (plain_ascii)
- dwCookie = icq_SendChannel1Message(dwUin, szUID, hContact, puszText, pCookieData);
- else
- dwCookie = icq_SendChannel1MessageW(dwUin, szUID, hContact, pwszText, pCookieData);
- // free the unicode message
- SAFE_FREE((void**)&pwszText);
-
- // This will stop the message dialog from waiting for the real message delivery ack
- if (pCookieData && pCookieData->nAckType == ACKTYPE_NONE) {
- SendProtoAck(hContact, dwCookie, ACKRESULT_SUCCESS, ACKTYPE_MESSAGE, nullptr);
- // We need to free this here since we will never see the real ack
- // The actual cookie value will still have to be returned to the message dialog though
- ReleaseCookie(dwCookie);
- }
- }
- // free the buffers if alloced
- if (bNeedFreeU) SAFE_FREE(&puszText);
-
- return dwCookie; // Success
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// SendUrl
-
-int CIcqProto::SendUrl(MCONTACT hContact, int, const char* url)
-{
- if (hContact == NULL || url == nullptr)
- return 0;
-
- DWORD dwUin;
- if (getContactUid(hContact, &dwUin, nullptr)) // Invalid contact
- return ReportGenericSendError(hContact, ACKTYPE_URL, "The receiver has an invalid user ID.");
-
- WORD wRecipientStatus = getContactStatus(hContact);
-
- // Failure
- if (!icqOnline()) {
- ReportGenericSendError(hContact, ACKTYPE_URL, "You cannot send messages when you are offline.");
- return 0;
- }
-
- // Set up the ack type
- cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_URL, hContact, dwUin, TRUE);
-
- // Format the body
- size_t nUrlLen = mir_strlen(url);
- char *szDesc = (char *)url + nUrlLen + 1;
- size_t nDescLen = mir_strlen(szDesc);
- size_t nBodyLen = nUrlLen + nDescLen + 2;
- char *szBody = (char *)_alloca(nBodyLen);
- mir_strcpy(szBody, szDesc);
- szBody[nDescLen] = -2; // Separator
- mir_strcpy(szBody + nDescLen + 1, url);
-
- if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) {
- int iRes = icq_SendDirectMessage(hContact, szBody, nBodyLen, pCookieData, nullptr);
- if (iRes)
- return iRes; // we succeded, return
- }
-
- // Rate check
- if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_LIMIT)) { // rate is too high, the message will not go thru...
- SAFE_FREE((void**)&pCookieData);
- return ReportGenericSendError(hContact, ACKTYPE_URL, "The message could not be delivered. You are sending too fast. Wait a while and try again.");
- }
-
- // Select channel and send
- WORD wPriority;
- if (wRecipientStatus == ID_STATUS_ONLINE || wRecipientStatus == ID_STATUS_FREECHAT)
- wPriority = 0x0001;
- else
- wPriority = 0x0021;
-
- DWORD dwCookie = icq_SendChannel2Message(dwUin, hContact, szBody, nBodyLen, wPriority, pCookieData, nullptr);
-
- // This will stop the message dialog from waiting for the real message delivery ack
- if (pCookieData->nAckType == ACKTYPE_NONE) {
- SendProtoAck(hContact, dwCookie, ACKRESULT_SUCCESS, ACKTYPE_URL, nullptr);
- // We need to free this here since we will never see the real ack
- // The actual cookie value will still have to be returned to the message dialog though
- ReleaseCookie(dwCookie);
- }
-
- return dwCookie; // Success
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_SetApparentMode - sets the visibility status
-
-int CIcqProto::SetApparentMode(MCONTACT hContact, int mode)
-{
- DWORD uin;
- uid_str uid;
- if (getContactUid(hContact, &uin, &uid))
- return 1; // Invalid contact
-
- if (hContact) {
- // Only 3 modes are supported
- if (mode == 0 || mode == ID_STATUS_ONLINE || mode == ID_STATUS_OFFLINE) {
- int oldMode = getWord(hContact, "ApparentMode", 0);
-
- // Don't send redundant updates
- if (mode != oldMode) {
- setWord(hContact, "ApparentMode", WORD(mode));
-
- // Not being online is only an error when in SS mode. This is not handled
- // yet so we just ignore this for now.
- if (icqOnline()) {
- if (oldMode != 0) { // Remove from old list
- if (oldMode == ID_STATUS_OFFLINE && getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0)) { // Need to remove Ignore item as well
- icq_removeServerPrivacyItem(hContact, uin, uid, getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0), SSI_ITEM_IGNORE);
-
- setWord(hContact, DBSETTING_SERVLIST_IGNORE, 0);
- }
- icq_sendChangeVisInvis(hContact, uin, uid, oldMode == ID_STATUS_OFFLINE, 0);
- }
- if (mode != 0) { // Add to new list
- if (mode == ID_STATUS_OFFLINE && getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0))
- return 0; // Success: offline by ignore item
-
- icq_sendChangeVisInvis(hContact, uin, uid, mode == ID_STATUS_OFFLINE, 1);
- }
- }
-
- return 0; // Success
- }
- }
- }
-
- return 1; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PrepareStatusNote - returns correct status note for given status
-
-char* CIcqProto::PrepareStatusNote(int nStatus)
-{
- char *szStatusNote = nullptr;
- BYTE bXStatus = getContactXStatus(NULL);
-
- // use custom status message as status note
- if (bXStatus)
- szStatusNote = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, nullptr);
-
- // get standard status message (no custom status defined)
- if (szStatusNote == nullptr) {
- mir_cslock l(m_modeMsgsMutex);
-
- char **pszStatusNote = MirandaStatusToAwayMsg(nStatus);
- if (pszStatusNote)
- szStatusNote = null_strdup(*pszStatusNote);
- }
-
- if (szStatusNote == nullptr) // nothing available. set empty status note
- szStatusNote = null_strdup("");
-
- return szStatusNote;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_SetStatus - sets the protocol status
-
-int CIcqProto::SetStatus(int iNewStatus)
-{
- int nNewStatus = MirandaStatusToSupported(iNewStatus);
-
- // check if netlib handles are ready
- if (!m_hNetlibUser)
- return 0;
-
- if (m_bTempVisListEnabled && icqOnline()) // remove temporary visible users
- sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_REMOVETEMPVISIBLE, BUL_TEMPVISIBLE);
-
- if (nNewStatus == m_iStatus)
- return 0;
-
- // clear custom status on status change
- if (getByte("XStatusReset", DEFAULT_XSTATUS_RESET))
- setXStatusEx(0, 0);
-
- // New status is OFFLINE
- if (nNewStatus == ID_STATUS_OFFLINE) { // for quick logoff
- if (icqOnline()) { // set offline status note (otherwise the old will remain)
- char *szOfflineNote = PrepareStatusNote(nNewStatus);
- SetStatusNote(szOfflineNote, 0, FALSE);
- SAFE_FREE(&szOfflineNote);
- }
-
- m_iDesiredStatus = nNewStatus;
-
- if (hServerConn) { // Connected, Send disconnect packet
- icq_sendCloseConnection();
- icq_serverDisconnect();
-
- m_bConnectionLost = false;
- debugLogA("Logged off.");
- }
- }
- else {
- switch (m_iStatus) {
-
- // We are offline and need to connect
- case ID_STATUS_OFFLINE:
- // Update user connection settings
- UpdateGlobalSettings();
-
- // Read UIN from database
- m_dwLocalUIN = getContactUin(NULL);
- if (m_dwLocalUIN == 0) {
- SetCurrentStatus(ID_STATUS_OFFLINE);
- ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_BADUSERID);
- icq_LogMessage(LOG_FATAL, LPGEN("You have not entered an ICQ number.\nConfigure this in Options -> Network -> ICQ and try again."));
- return 0;
- }
-
- // Set status to 'Connecting'
- m_iDesiredStatus = nNewStatus;
- SetCurrentStatus(ID_STATUS_CONNECTING);
-
- // Read password from database
- {
- char *pszPwd = GetUserPassword(FALSE);
- if (pszPwd)
- icq_login(pszPwd);
- else
- RequestPassword();
- }
- break;
-
- // We are connecting... We only need to change the going online status
- case ID_STATUS_CONNECTING:
- m_iDesiredStatus = nNewStatus;
- break;
-
- // We are already connected so we should just change status
- default:
- SetCurrentStatus(nNewStatus);
-
- char *szStatusNote = PrepareStatusNote(nNewStatus);
-
- //! This is a bit tricky, we do trigger status note change thread and then
- // change the status note right away (this spares one packet) - so SetStatusNote()
- // will only change User Details Directory
- SetStatusNote(szStatusNote, 6000, FALSE);
-
- if (m_iStatus == ID_STATUS_INVISIBLE) {
- if (m_bSsiEnabled)
- updateServVisibilityCode(3);
- icq_setstatus(MirandaStatusToIcq(m_iStatus), szStatusNote);
- }
- else {
- icq_setstatus(MirandaStatusToIcq(m_iStatus), szStatusNote);
- if (m_bSsiEnabled)
- updateServVisibilityCode(4);
- }
- SAFE_FREE(&szStatusNote);
-
- mir_cslock l(m_modeMsgsMutex);
- char ** pszStatusNote = MirandaStatusToAwayMsg(m_iStatus);
- if (pszStatusNote)
- icq_sendSetAimAwayMsgServ(*pszStatusNote);
- else // clear the away message
- icq_sendSetAimAwayMsgServ(nullptr);
- }
- }
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// GetAwayMsgThread - return a contact's status message
-
-struct status_message_thread_data
-{
- MCONTACT hContact;
- char *szMessage;
- HANDLE hProcess;
-};
-
-void __cdecl CIcqProto::GetAwayMsgThread(void *pStatusData)
-{
- Thread_SetName("ICQ: GetAwayMsgThread");
-
- status_message_thread_data *pThreadData = (status_message_thread_data*)pStatusData;
- if (pThreadData) {
- // wait a little
- Sleep(100);
-
- setStatusMsgVar(pThreadData->hContact, pThreadData->szMessage, false);
-
- wchar_t *tszMsg = mir_utf8decodeW(pThreadData->szMessage);
- ProtoBroadcastAck(pThreadData->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, pThreadData->hProcess, (LPARAM)tszMsg);
- mir_free(tszMsg);
-
- SAFE_FREE(&pThreadData->szMessage);
- SAFE_FREE((void**)&pThreadData);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_GetAwayMsg - returns a contact's away message
-
-HANDLE CIcqProto::GetAwayMsg(MCONTACT hContact)
-{
- DWORD dwUin;
- uid_str szUID;
- if (getContactUid(hContact, &dwUin, &szUID))
- return nullptr; // Invalid contact
-
- if (!dwUin || !CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES)) { // No individual status messages, check if the contact has Status Note, if yes give it
- char *szStatusNote = getSettingStringUtf(hContact, DBSETTING_STATUS_NOTE, nullptr);
-
- if (mir_strlen(szStatusNote) > 0) { // Give Status Note
- status_message_thread_data *pThreadData = (status_message_thread_data*)SAFE_MALLOC(sizeof(status_message_thread_data));
-
- pThreadData->hContact = hContact;
- pThreadData->szMessage = szStatusNote;
- pThreadData->hProcess = (HANDLE)GenerateCookie(0);
- ForkThread(&CIcqProto::GetAwayMsgThread, pThreadData);
-
- return pThreadData->hProcess;
- }
- SAFE_FREE(&szStatusNote);
- }
-
- if (!icqOnline())
- return nullptr;
-
- WORD wStatus = getContactStatus(hContact);
-
- if (dwUin) {
- int wMessageType = 0;
-
- switch (wStatus) {
- case ID_STATUS_ONLINE:
- if (CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES))
- wMessageType = MTYPE_AUTOONLINE;
- break;
-
- case ID_STATUS_AWAY:
- wMessageType = MTYPE_AUTOAWAY;
- break;
-
- case ID_STATUS_NA:
- wMessageType = MTYPE_AUTONA;
- break;
-
- case ID_STATUS_OCCUPIED:
- wMessageType = MTYPE_AUTOBUSY;
- break;
-
- case ID_STATUS_DND:
- wMessageType = MTYPE_AUTODND;
- break;
-
- case ID_STATUS_FREECHAT:
- wMessageType = MTYPE_AUTOFFC;
- break;
- }
-
- if (wMessageType) {
- if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) {
- int iRes = icq_sendGetAwayMsgDirect(hContact, wMessageType);
- if (iRes) return (HANDLE)iRes; // we succeded, return
- }
-
- WORD wVer = getWord(hContact, "Version", 0) <= 8 ? 8 : ICQ_VERSION;
- if (CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES))
- return (HANDLE)icq_sendGetAwayMsgServExt(hContact, dwUin, szUID, wMessageType, wVer);
-
- return (HANDLE)icq_sendGetAwayMsgServ(hContact, dwUin, wMessageType, wVer);
- }
- }
- else { // AIM contact
- if (wStatus == ID_STATUS_AWAY)
- return (HANDLE)icq_sendGetAimAwayMsgServ(hContact, szUID, MTYPE_AUTOAWAY);
- }
-
- return nullptr; // Failure
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PSR_AWAYMSG - processes received status mode message
-
-int CIcqProto::RecvAwayMsg(MCONTACT hContact, int, PROTORECVEVENT* evt)
-{
- setStatusMsgVar(hContact, evt->szMessage, false);
-
- wchar_t* pszMsg = mir_utf8decodeW(evt->szMessage);
- ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)evt->lParam, (LPARAM)pszMsg);
- mir_free(pszMsg);
- return 0;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_SetAwayMsg - sets the away status message
-
-int CIcqProto::SetAwayMsg(int status, const wchar_t* msg)
-{
- mir_cslock l(m_modeMsgsMutex);
-
- char **ppszMsg = MirandaStatusToAwayMsg(MirandaStatusToSupported(status));
- if (!ppszMsg)
- return 1; // Failure
-
- // Prepare UTF-8 status message
- char *szNewUtf = make_utf8_string(msg);
-
- if (mir_strcmp(szNewUtf, *ppszMsg)) {
- // Free old message
- SAFE_FREE(ppszMsg);
-
- // Set new message
- *ppszMsg = szNewUtf;
- szNewUtf = nullptr;
-
- if ((m_iStatus == status) && icqOnline()) { // update current status note
- char *szNote = *ppszMsg ? *ppszMsg : "";
-
- BYTE bXStatus = getContactXStatus(NULL);
- if (!bXStatus)
- SetStatusNote(szNote, 1000, FALSE);
-
- icq_sendSetAimAwayMsgServ(*ppszMsg);
- }
- }
- SAFE_FREE(&szNewUtf);
-
- return 0; // Success
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// GetMyAwayMsg - obtain the current away message
-
-INT_PTR CIcqProto::GetMyAwayMsg(WPARAM wParam, LPARAM lParam)
-{
- mir_cslock l(m_modeMsgsMutex);
-
- char **ppszMsg = MirandaStatusToAwayMsg(wParam ? wParam : m_iStatus);
-
- if (!ppszMsg || !*ppszMsg)
- return 0;
-
- size_t nMsgLen = mir_strlen(*ppszMsg) + 1;
-
- if (lParam & SGMA_UNICODE) {
- WCHAR *szMsg = (WCHAR*)_alloca(nMsgLen * sizeof(WCHAR));
-
- make_unicode_string_static(*ppszMsg, szMsg, nMsgLen);
- return (INT_PTR)mir_wstrdup(szMsg);
- }
- else { // convert to ansi
- char *szMsg = (char*)_alloca(nMsgLen);
-
- if (utf8_decode_static(*ppszMsg, szMsg, nMsgLen))
- return (INT_PTR)mir_strdup(szMsg);
- }
-
- return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// PS_UserIsTyping - sends a UTN notification
-
-int CIcqProto::UserIsTyping(MCONTACT hContact, int type)
-{
- if (hContact && icqOnline()) {
- if (CheckContactCapabilities(hContact, CAPF_TYPING)) {
- switch (type) {
- case PROTOTYPE_SELFTYPING_ON:
- sendTypingNotification(hContact, MTN_BEGUN);
- return 0;
-
- case PROTOTYPE_SELFTYPING_OFF:
- sendTypingNotification(hContact, MTN_FINISHED);
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// OnEvent - maintain protocol events
-
-void CIcqProto::OnErase()
-{
- char szDbSetting[MAX_PATH];
- mir_snprintf(szDbSetting, "%sP2P", m_szModuleName);
- db_delete_module(0, szDbSetting);
- mir_snprintf(szDbSetting, "%sSrvGroups", m_szModuleName);
- db_delete_module(0, szDbSetting);
- mir_snprintf(szDbSetting, "%sGroups", m_szModuleName);
- db_delete_module(0, szDbSetting);
-}
diff --git a/protocols/IcqOscarJ/src/icq_proto.h b/protocols/IcqOscarJ/src/icq_proto.h
deleted file mode 100644
index f50c445126..0000000000
--- a/protocols/IcqOscarJ/src/icq_proto.h
+++ /dev/null
@@ -1,902 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera, George Hazan
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Protocol Interface declarations
-// -----------------------------------------------------------------------------
-
-#ifndef _ICQ_PROTO_H_
-#define _ICQ_PROTO_H_
-
-#include "m_system.h"
-#include "m_protoint.h"
-
-#define LISTSIZE 100
-
-#define XSTATUS_COUNT 86
-
-// for InfoUpdate
-struct userinfo
-{
- DWORD dwUin;
- MCONTACT hContact;
- time_t queued;
-};
-
-struct CIcqProto : public PROTO<CIcqProto>
-{
- CIcqProto(const char*, const wchar_t*);
- ~CIcqProto();
-
- //====================================================================================
- // PROTO_INTERFACE
- //====================================================================================
-
- MCONTACT AddToList( int flags, PROTOSEARCHRESULT *psr) override;
- MCONTACT AddToListByEvent( int flags, int iContact, MEVENT hDbEvent) override;
-
- int Authorize(MEVENT hDbEvent) override;
- int AuthDeny(MEVENT hDbEvent, const wchar_t *szReason) override;
- int AuthRecv(MCONTACT hContact, PROTORECVEVENT*) override;
- int AuthRequest(MCONTACT hContact, const wchar_t *szMessage) override;
-
- HANDLE FileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szPath) override;
- int FileCancel(MCONTACT hContact, HANDLE hTransfer) override;
- int FileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szReason) override;
- int FileResume( HANDLE hTransfer, int *action, const wchar_t **szFilename) override;
-
- INT_PTR GetCaps(int type, MCONTACT hContact = NULL) override;
- int GetInfo(MCONTACT hContact, int infoType) override;
-
- HANDLE SearchBasic(const wchar_t *id) override;
- HANDLE SearchByEmail(const wchar_t *email) override;
- HANDLE SearchByName(const wchar_t *nick, const wchar_t *firstName, const wchar_t *lastName) override;
- HWND SearchAdvanced(HWND owner) override;
- HWND CreateExtendedSearchUI(HWND owner) override;
-
- int RecvContacts(MCONTACT hContact, PROTORECVEVENT*) override;
- MEVENT RecvMsg(MCONTACT hContact, PROTORECVEVENT*) override;
-
- int SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList) override;
- HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles) override;
- int SendMsg(MCONTACT hContact, int flags, const char *msg) override;
- int SendUrl(MCONTACT hContact, int flags, const char *url) override;
-
- int SetApparentMode(MCONTACT hContact, int mode) override;
- int SetStatus(int iNewStatus) override;
-
- HANDLE GetAwayMsg(MCONTACT hContact) override;
- int RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT *evt) override;
- int SetAwayMsg(int m_iStatus, const wchar_t *msg) override;
-
- int UserIsTyping(MCONTACT hContact, int type) override;
-
- void OnContactDeleted(MCONTACT) override;
- void OnErase() override;
- void OnModulesLoaded() override;
- void OnShutdown() override;
-
- //====| Services |====================================================================
- INT_PTR __cdecl AddServerContact(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl GetInfoSetting(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl ChangeInfoEx(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl GetAvatarCaps(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl GetAvatarInfo(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl GetMyAvatar(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl GetMyAwayMsg(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl GetXStatusEx(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl GetXStatusIcon(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl GrantAuthorization(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl menuXStatus(WPARAM wParam,LPARAM lParam,LPARAM fParam);
- INT_PTR __cdecl OpenWebProfile(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl RequestAdvStatusIconIdx(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl RequestAuthorization(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl RequestXStatusDetails(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl RevokeAuthorization(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl SendSms(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl SendYouWereAdded(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl SetMyAvatar(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl SetNickName(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl SetXStatusEx(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl ShowXStatusDetails(WPARAM wParam, LPARAM lParam);
-
- INT_PTR __cdecl OnCreateAccMgrUI(WPARAM, LPARAM);
-
- //====| Events |======================================================================
- int __cdecl OnIdleChanged(WPARAM, LPARAM);
- int __cdecl OnOptionsInit(WPARAM, LPARAM);
- int __cdecl OnPreBuildContactMenu(WPARAM, LPARAM);
- int __cdecl OnUserInfoInit(WPARAM, LPARAM);
-
- int __cdecl OnPreBuildStatusMenu(WPARAM, LPARAM);
-
- //====| Data |========================================================================
- HNETLIBUSER m_hDirectNetlibUser;
-
- BYTE m_bGatewayMode;
- BYTE m_bSecureLogin;
- BYTE m_bSecureConnection;
- BYTE m_bLegacyFix;
- WORD m_wAnsiCodepage;
- BYTE m_bDCMsgEnabled;
- BYTE m_bTempVisListEnabled;
- BYTE m_bSsiEnabled;
- BYTE m_bSsiSimpleGroups;
- BYTE m_bAvatarsEnabled;
- BYTE m_bXStatusEnabled;
- BYTE m_bMoodsEnabled;
-
- mir_cs localSeqMutex;
- mir_cs connectionHandleMutex;
-
- bool m_bIdleMode;
- DWORD m_dwLocalUIN;
- BYTE m_bConnectionLost;
-
- char m_szPassword[PASSWORDMAXLEN+1];
- BYTE m_bRememberPwd;
-
- int cheekySearchId;
- DWORD cheekySearchUin;
- char* cheekySearchUid;
-
- /*******************************************************************
- * Function declarations
- *******************************************************************/
-
- //----| capabilities.cpp |------------------------------------------------------------
- // Deletes all oscar capabilities for a given contact.
- void ClearAllContactCapabilities(MCONTACT hContact);
-
- // Deletes one or many oscar capabilities for a given contact.
- void ClearContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities);
-
- // Sets one or many oscar capabilities for a given contact.
- void SetContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities);
-
- // Returns true if the given contact supports the requested capabilites.
- BOOL CheckContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities);
-
- // Scans a binary buffer for oscar capabilities and adds them to the contact.
- void AddCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength);
-
- // Scans a binary buffer for oscar capabilities and sets them to the contact.
- void SetCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength, BOOL bReset);
-
- //----| chan_01login.cpp |------------------------------------------------------------
- void handleLoginChannel(BYTE *buf, size_t datalen, serverthread_info *info);
-
- //----| chan_02data.cpp |-------------------------------------------------------------
- void handleDataChannel(BYTE *buf, size_t wLen, serverthread_info *info);
-
- void LogFamilyError(WORD wFamily, WORD wError);
-
- //----| chan_03error.cpp |------------------------------------------------------------
- void handleErrorChannel(unsigned char *buf, size_t datalen);
-
- //----| chan_04close.cpp |------------------------------------------------------------
- void handleCloseChannel(BYTE *buf, size_t datalen, serverthread_info *info);
- void handleLoginReply(BYTE *buf, size_t datalen, serverthread_info *info);
- void handleMigration(serverthread_info *info);
- void handleSignonError(WORD wError);
-
- int connectNewServer(serverthread_info *info);
-
- //----| chan_05ping.cpp |-------------------------------------------------------------
- void handlePingChannel(BYTE *buf, size_t wLen);
-
- void StartKeepAlive(serverthread_info *info);
- void StopKeepAlive(serverthread_info *info);
- void CheckKeepAlive(serverthread_info *info);
-
- //----| cookies.cpp |-----------------------------------------------------------------
- mir_cs cookieMutex; // we want this in avatar thread, used as queue lock
- OBJLIST<icq_cookie_info> cookies;
- WORD wCookieSeq;
-
- DWORD AllocateCookie(BYTE bType, WORD wIdent, MCONTACT hContact, void *pvExtra);
- void FreeCookie(DWORD dwCookie);
- void FreeCookieByData(BYTE bType, void *pvExtra);
- void ReleaseCookie(DWORD dwCookie);
- DWORD GenerateCookie(WORD wIdent);
-
- int GetCookieType(DWORD dwCookie);
-
- int FindCookie(DWORD wCookie, MCONTACT *phContact, void **ppvExtra);
- int FindCookieByData(void *pvExtra, DWORD *pdwCookie, MCONTACT *phContact);
- int FindCookieByType(BYTE bType, DWORD *pdwCookie, MCONTACT *phContact, void **ppvExtra);
- int FindMessageCookie(DWORD dwMsgID1, DWORD dwMsgID2, DWORD *pdwCookie, MCONTACT *phContact, cookie_message_data **ppvExtra);
-
- void InitMessageCookie(cookie_message_data *pCookie);
- cookie_message_data* CreateMessageCookie(WORD bMsgType, BYTE bAckType);
- cookie_message_data* CreateMessageCookieData(BYTE bMsgType, MCONTACT hContact, DWORD dwUin, int bUseSrvRelay);
-
- void RemoveExpiredCookies(void);
-
- //----| directpackets.cpp |-----------------------------------------------------------
- void icq_sendDirectMsgAck(directconnect* dc, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, char* szCap);
- DWORD icq_sendGetAwayMsgDirect(MCONTACT hContact, int type);
- void icq_sendAwayMsgReplyDirect(directconnect *dc, WORD wCookie, BYTE msgType, const char** szMsg);
- void icq_sendFileAcceptDirect(MCONTACT hContact, filetransfer *ft);
- void icq_sendFileDenyDirect(MCONTACT hContact, filetransfer *ft, const char *szReason);
- int icq_sendFileSendDirectv7(filetransfer *ft, const char *pszFiles);
- int icq_sendFileSendDirectv8(filetransfer *ft, const char *pszFiles);
- DWORD icq_SendDirectMessage(MCONTACT hContact, const char *szMessage, size_t nBodyLength, cookie_message_data *pCookieData, char *szCap);
- void icq_sendXtrazRequestDirect(MCONTACT hContact, DWORD dwCookie, char* szBody, size_t nBodyLen, WORD wType);
- void icq_sendXtrazResponseDirect(MCONTACT hContact, WORD wCookie, char* szBody, size_t nBodyLen, WORD wType);
-
- //----| fam_01service.cpp |-----------------------------------------------------------
- void handleServiceFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info);
- char* buildUinList(int subtype, size_t wMaxLen, MCONTACT *hContactResume);
- void sendEntireListServ(WORD wFamily, WORD wSubtype, int listType);
- void setUserInfo(void);
- void handleServUINSettings(int nPort, serverthread_info *info);
-
- //----| fam_02location.cpp |----------------------------------------------------------
- void handleLocationFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader);
- void handleLocationUserInfoReply(BYTE* buf, size_t wLen, DWORD dwCookie);
-
- //----| fam_03buddy.cpp |-------------------------------------------------------------
- void handleBuddyFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info);
- void handleReplyBuddy(BYTE *buf, size_t wPackLen);
- void handleUserOffline(BYTE *buf, size_t wPackLen);
- void handleUserOnline(BYTE *buf, size_t wPackLen, serverthread_info *info);
- void parseStatusNote(DWORD dwUin, char *szUid, MCONTACT hContact, oscar_tlv_chain *pChain);
- void handleNotifyRejected(BYTE *buf, size_t wPackLen);
-
- //----| fam_04message.cpp |-----------------------------------------------------------
- icq_mode_messages m_modeMsgs;
- mir_cs m_modeMsgsMutex;
- HANDLE m_modeMsgsEvent;
-
- void handleMsgFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader);
-
- void handleReplyICBM();
- void handleRecvServMsg(BYTE *buf, size_t wLen, DWORD dwRef);
- void handleRecvServMsgType1(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwRef);
- void handleRecvServMsgType2(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2);
- void handleRecvServMsgType4(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, DWORD dwRef);
- void handleRecvServMsgError(BYTE *buf, size_t wLen, DWORD dwRef);
- void handleRecvMsgResponse(BYTE *buf, size_t wLen);
- void handleServerAck(BYTE *buf, size_t wLen, DWORD dwRef);
- void handleStatusMsgReply(const char *szPrefix, MCONTACT hContact, DWORD dwUin, int bMsgType, WORD wCookie, const char *szMsg);
- void handleTypingNotification(BYTE *buf, size_t wLen);
- void handleMissedMsg(BYTE *buf, size_t wLen);
- void handleOffineMessagesReply(DWORD dwRef);
- void handleRecvServMsgContacts(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwID1, DWORD dwID2, WORD wCommand);
- void handleRuntimeError(WORD wError);
-
- void parseServRelayData(BYTE *pDataBuf, size_t wLen, MCONTACT hContact, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wAckType);
- void parseServRelayPluginData(BYTE *pDataBuf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wAckType, BYTE bFlags, WORD wStatus, WORD wCookie, WORD wVersion);
-
- HANDLE handleMessageAck(DWORD dwUin, char *szUID, WORD wCookie, int type, PBYTE buf, BYTE bFlags);
- void handleMessageTypes(DWORD dwUin, char *szUID, DWORD dwTimestamp, DWORD dwMsgID, DWORD dwMsgID2, WORD wCookie, WORD wVersion, int type, int flags, WORD wAckType, size_t dwDataLen, size_t wMsgLen, char *pMsg, int nMsgFlags, message_ack_params *pAckParams);
- void sendMessageTypesAck(MCONTACT hContact, int bUnicode, message_ack_params *pArgs);
- void sendTypingNotification(MCONTACT hContact, WORD wMTNCode);
-
- int unpackPluginTypeId(BYTE **pBuffer, size_t *pwLen, int *pTypeId, WORD *pFunctionId, BOOL bThruDC);
-
- char* convertMsgToUserSpecificUtf(MCONTACT hContact, const char *szMsg);
-
- //----| fam_09bos.cpp |---------------------------------------------------------------
- void handleBosFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader);
- void handlePrivacyRightsReply(unsigned char *pBuffer, size_t wBufferLength);
- void makeContactTemporaryVisible(MCONTACT hContact);
-
- //----| fam_0alookup.cpp |------------------------------------------------------------
- void handleLookupFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader);
-
- void handleLookupEmailReply(BYTE* buf, size_t wLen, DWORD dwCookie);
- void ReleaseLookupCookie(DWORD dwCookie, cookie_search *pCookie);
-
- //----| fam_0bstatus.cpp |------------------------------------------------------------
- void handleStatusFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader);
-
- //----| fam_13servclist.cpp |---------------------------------------------------------
- BOOL bIsSyncingCL;
-
- WORD m_wServerListLimits[0x20];
- WORD m_wServerListGroupMaxContacts;
- WORD m_wServerListRecordNameMaxLength;
-
- void handleServCListFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader, serverthread_info *info);
- void handleServerCListRightsReply(BYTE *buf, size_t wLen);
- void handleServerCListAck(cookie_servlist_action* sc, WORD wError);
- void handleServerCListReply(BYTE *buf, size_t wLen, WORD wFlags, serverthread_info *info);
- void handleServerCListItemAdd(WORD wItemId, WORD wItemType, oscar_tlv_chain *pItemData);
- void handleServerCListItemUpdate(const char *szRecordName, WORD wItemType, oscar_tlv_chain *pItemData);
- void handleServerCListItemDelete(const char *szRecordName, WORD wItemId, WORD wItemType);
- void handleRecvAuthRequest(BYTE *buf, size_t wLen);
- void handleRecvAuthResponse(BYTE *buf, size_t wLen);
- void handleRecvAdded(BYTE *buf, size_t wLen);
-
- MCONTACT HContactFromRecordName(const char *szRecordName, int *bAdded);
-
- void icq_sendServerBeginOperation(int bImport);
- void icq_sendServerEndOperation();
- void sendRosterAck(void);
-
- int getServerDataFromItemTLV(oscar_tlv_chain* pChain, unsigned char *buf);
- DWORD updateServerGroupData(WORD wGroupId, void *groupData, int groupSize, DWORD dwOperationFlags);
- void updateServAvatarHash(BYTE *pHash, int size);
- void updateServVisibilityCode(BYTE bCode);
-
- //----| fam_15icqserver.cpp |---------------------------------------------------------
- void handleIcqExtensionsFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader);
-
- void handleExtensionError(BYTE *buf, size_t wPackLen);
- void handleExtensionServerInfo(BYTE *buf, size_t wPackLen, WORD wFlags);
- void handleExtensionMetaResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie, WORD wFlags);
-
- int parseUserInfoRecord(MCONTACT hContact, oscar_tlv *pData, UserInfoRecordItem pRecordDef[], int nRecordDef, int nMaxRecords);
-
- void handleDirectoryQueryResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie, WORD wReplySubtype, WORD wFlags);
- void handleDirectoryUpdateResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie);
-
- void parseDirectoryUserDetailsData(MCONTACT hContact, oscar_tlv_chain *cDetails, cookie_directory_data *pCookieData, WORD wReplySubType);
- void parseDirectorySearchData(oscar_tlv_chain *cDetails, DWORD dwCookie, WORD wReplySubType);
-
- void parseSearchReplies(unsigned char *databuf, size_t wPacketLen, WORD wCookie, WORD wReplySubtype, BYTE bResultCode);
- void parseUserInfoUpdateAck(WORD wCookie, WORD wReplySubtype, BYTE bResultCode);
-
- void ReleaseSearchCookie(DWORD dwCookie, cookie_search *pCookie);
-
- //----| fam_17signon.cpp |------------------------------------------------------------
- void handleAuthorizationFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info);
- void handleAuthKeyResponse(BYTE *buf, size_t wPacketLen, serverthread_info *info);
-
- void sendClientAuth(const char *szKey, size_t wKeyLen, BOOL bSecure);
-
- //----| icq_avatars.cpp |-------------------------------------------------------------
- mir_cs m_avatarsMutex;
- LIST<avatars_request> m_arAvatars;
-
- BOOL m_avatarsConnectionPending;
- avatars_server_connection *m_avatarsConnection;
-
- void requestAvatarConnection();
- void __cdecl AvatarThread(avatars_server_connection *pInfo);
-
- void handleAvatarOwnerHash(BYTE bFlags, BYTE *pData, size_t nDataLen);
- void handleAvatarContactHash(DWORD dwUIN, char *szUID, MCONTACT hContact, BYTE *pHash, size_t nHashLen);
-
- wchar_t* GetOwnAvatarFileName();
- void GetFullAvatarFileName(int dwUin, const char *szUid, int dwFormat, wchar_t *pszDest, size_t cbLen);
- void GetAvatarFileName(int dwUin, const char *szUid, wchar_t *pszDest, size_t cbLen);
- int IsAvatarChanged(MCONTACT hContact, const BYTE *pHash, size_t nHashLen);
-
- int GetAvatarData(MCONTACT hContact, DWORD dwUin, const char *szUid, const BYTE *hash, size_t hashlen, const wchar_t *file);
- int SetAvatarData(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen);
-
- void StartAvatarThread(HNETLIBCONN hConn, char* cookie, size_t cookieLen);
- void StopAvatarThread();
-
- //----| icq_clients.cpp |-------------------------------------------------------------
- const char* detectUserClient(MCONTACT hContact, int nIsICQ, WORD wUserClass, DWORD dwOnlineSince, const char *szCurrentClient, WORD wVersion, DWORD dwFT1, DWORD dwFT2, DWORD dwFT3, DWORD dwDirectCookie, DWORD dwWebPort, BYTE *caps, size_t wLen, BYTE *bClientId, char *szClientBuf);
-
- //----| icq_db.cpp |------------------------------------------------------------------
- MEVENT AddEvent(MCONTACT hContact, WORD wType, DWORD dwTime, DWORD flags, size_t cbBlob, PBYTE pBlob);
- int IsICQContact(MCONTACT hContact);
-
- int getSetting(MCONTACT hContact, const char *szSetting, DBVARIANT *dbv);
- double getSettingDouble(MCONTACT hContact, const char *szSetting, double dDef);
- int getSettingStringStatic(MCONTACT hContact, const char *szSetting, char *dest, size_t dest_len);
- char* getSettingStringUtf(MCONTACT hContact, const char *szModule, const char *szSetting, char *szDef);
- char* getSettingStringUtf(MCONTACT hContact, const char *szSetting, char *szDef);
- int getContactUid(MCONTACT hContact, DWORD *pdwUin, uid_str *ppszUid);
- DWORD getContactUin(MCONTACT hContact);
- WORD getContactStatus(MCONTACT hContact);
- char* getContactCListGroup(MCONTACT hContact);
-
- int setSettingDouble(MCONTACT hContact, const char *szSetting, double dValue);
- int setSettingBlob(MCONTACT hContact, const char *szSetting, const BYTE *pValue, size_t cbValue);
- int setContactHidden(MCONTACT hContact, BYTE bHidden);
- void setStatusMsgVar(MCONTACT hContact, char* szStatusMsg, bool isAnsi);
-
- //----| icq_direct.cpp |--------------------------------------------------------------
- mir_cs directConnListMutex;
- LIST<directconnect> directConns;
-
- mir_cs expectedFileRecvMutex;
- LIST<filetransfer> expectedFileRecvs;
-
- void __cdecl icq_directThread(struct directthreadstartinfo* dtsi);
-
- void handleDirectPacket(directconnect* dc, PBYTE buf, size_t wLen);
- void sendPeerInit_v78(directconnect* dc);
- void sendPeerInitAck(directconnect* dc);
- void sendPeerMsgInit(directconnect* dc, DWORD dwSeq);
- void sendPeerFileInit(directconnect* dc);
- int sendDirectPacket(directconnect* dc, icq_packet* pkt);
-
- void CloseContactDirectConns(MCONTACT hContact);
- directconnect* FindFileTransferDC(filetransfer* ft);
- filetransfer* FindExpectedFileRecv(DWORD dwUin, DWORD dwTotalSize);
- BOOL IsDirectConnectionOpen(MCONTACT hContact, int type, int bPassive);
- void OpenDirectConnection(MCONTACT hContact, int type, void* pvExtra);
- void CloseDirectConnection(directconnect *dc);
- int SendDirectMessage(MCONTACT hContact, icq_packet *pkt);
-
- //----| icq_directmsg.cpp |-----------------------------------------------------------
- void handleDirectMessage(directconnect* dc, PBYTE buf, size_t wLen);
- void handleDirectGreetingMessage(directconnect* dc, PBYTE buf, size_t wLen, WORD wCommand, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, WORD wStatus, WORD wFlags);
-
- //----| icq_filerequests.cpp |--------------------------------------------------------
- filetransfer* CreateFileTransfer(MCONTACT hContact, DWORD dwUin, int nVersion);
-
- void handleFileAck(PBYTE buf, size_t wLen, DWORD dwUin, DWORD dwCookie, WORD wStatus);
- void handleFileRequest(PBYTE buf, DWORD dwUin, DWORD dwCookie, DWORD dwID1, DWORD dwID2, char* pszDescription, int nVersion, BOOL bDC);
- void handleDirectCancel(void);
-
- void icq_CancelFileTransfer(filetransfer* ft);
-
- //----| icq_filetransfer.cpp |--------------------------------------------------------
- void icq_sendFileResume(filetransfer *ft, int action, const char *szFilename);
-
- void handleFileTransferPacket(directconnect *dc, PBYTE buf, size_t wLen);
- void handleFileTransferIdle(directconnect *dc);
-
- //----| icq_infoupdate.cpp |----------------------------------------------------------
- mir_cs infoUpdateMutex;
- HANDLE hInfoQueueEvent;
- int nInfoUserCount;
- int bInfoPendingUsers;
- BOOL bInfoUpdateEnabled;
- BOOL bInfoUpdateRunning;
- HANDLE hInfoThread;
- DWORD dwInfoActiveRequest;
- userinfo m_infoUpdateList[LISTSIZE];
-
- void __cdecl InfoUpdateThread(void*);
-
- void icq_InitInfoUpdate(void); // Queues all outdated users
- BOOL icq_QueueUser(MCONTACT hContact); // Queue one UIN to the list for updating
- void icq_DequeueUser(DWORD dwUin); // Remove one UIN from the list
- void icq_RescanInfoUpdate(); // Add all outdated contacts to the list
- void icq_InfoUpdateCleanup(void); // Clean up on exit
- void icq_EnableUserLookup(BOOL bEnable); // Enable/disable user info lookups
-
- //----| log.cpp |-----------------------------------------------------------------
- BOOL bErrorBoxVisible;
-
- void __cdecl icq_LogMessageThread(void* arg);
-
- void icq_LogMessage(int level, const char *szMsg);
- void icq_LogUsingErrorCode(int level, DWORD dwError, const char *szMsg); //szMsg is optional
- void icq_LogFatalParam(const char *szMsg, WORD wError);
-
- //----| icq_packet.cpp |--------------------------------------------------------------
- void ppackLETLVLNTSfromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType);
- void ppackLETLVWordLNTSfromDB(PBYTE *buf, size_t *buflen, WORD w, const char *szSetting, WORD wType);
- void ppackLETLVLNTSBytefromDB(PBYTE *buf, size_t *buflen, const char *szSetting, BYTE b, WORD wType);
-
- void ppackTLVStringFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType);
- void ppackTLVStringUtfFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType);
- void ppackTLVDateFromDB(PBYTE *buf, size_t *buflen, const char *szSettingYear, const char *szSettingMonth, const char *szSettingDay, WORD wType);
-
- int ppackTLVWordStringItemFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wTypeID, WORD wTypeData, WORD wID);
- int ppackTLVWordStringUtfItemFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wTypeID, WORD wTypeData, WORD wID);
-
- BOOL unpackUID(BYTE **ppBuf, size_t *pwLen, DWORD *pdwUIN, uid_str *ppszUID);
-
- //----| icq_popups.cpp |--------------------------------------------------------------
- int ShowPopupMsg(MCONTACT hContact, const char *szTitle, const char *szMsg, BYTE bType);
-
- //----| icq_proto.cpp |--------------------------------------------------------------
- void __cdecl CheekySearchThread( void* );
-
- void __cdecl GetAwayMsgThread( void *pStatusData );
-
- char* PrepareStatusNote(int nStatus);
-
- //----| icq_rates.cpp |---------------------------------------------------------------
- mir_cs m_ratesMutex;
- rates *m_rates;
-
- rates_queue *m_ratesQueue_Request; // rate queue for xtraz requests
- rates_queue *m_ratesQueue_Response; // rate queue for msg responses
-
- int handleRateItem(rates_queue_item *item, int nQueueType = RQT_DEFAULT, int nMinDelay = 0, BOOL bAllowDelay = TRUE);
-
- //----| icq_server.cpp |--------------------------------------------------------------
- HNETLIBCONN hServerConn;
- WORD wListenPort;
- WORD wLocalSequence;
- UINT serverThreadId;
- HANDLE serverThreadHandle;
-
- __inline bool icqOnline() const
- { return (m_iStatus != ID_STATUS_OFFLINE && m_iStatus != ID_STATUS_CONNECTING);
- }
-
- void __cdecl SendPacketAsyncThread(icq_packet* pArgs);
- void __cdecl ServerThread(serverthread_start_info *infoParam);
-
- void icq_serverDisconnect(void);
- void icq_login(const char* szPassword);
-
- int handleServerPackets(BYTE *buf, int len, serverthread_info *info);
- void sendServPacket(icq_packet *pPacket);
- void sendServPacketAsync(icq_packet *pPacket);
-
- int IsServerOverRate(WORD wFamily, WORD wCommand, int nLevel);
-
- //----| icq_servlist.cpp |------------------------------------------------------------
- HANDLE hHookSettingChanged;
- HANDLE hHookContactDeleted;
- HANDLE hHookCListGroupChange;
- mir_cs servlistMutex;
-
- DWORD* pdwServerIDList;
- int nServerIDListCount;
- int nServerIDListSize;
-
- // server-list update board
- mir_cs servlistQueueMutex;
- int servlistQueueCount;
- int servlistQueueSize;
- ssiqueueditems **servlistQueueList;
- int servlistQueueState;
- HANDLE servlistQueueThreadHandle;
- int servlistEditCount;
-
- void servlistBeginOperation(int operationCount, int bImport);
- void servlistEndOperation(int operationCount);
-
- void __cdecl servlistQueueThread(void* queueState);
-
- void servlistQueueAddGroupItem(servlistgroupitem* pGroupItem, int dwTimeout);
- int servlistHandlePrimitives(DWORD dwOperation);
- void servlistProcessLogin();
-
- void servlistPostPacket(icq_packet* packet, DWORD dwCookie, DWORD dwOperation, DWORD dwTimeout);
- void servlistPostPacketDouble(icq_packet* packet1, DWORD dwCookie, DWORD dwOperation, DWORD dwTimeout, icq_packet* packet2, WORD wAction2);
-
- // server-list pending queue
- int servlistPendingCount;
- int servlistPendingSize;
- servlistpendingitem** servlistPendingList;
-
- int servlistPendingFindItem(int nType, MCONTACT hContact, const char *pszGroup);
- void servlistPendingAddItem(servlistpendingitem* pItem);
- servlistpendingitem* servlistPendingRemoveItem(int nType, MCONTACT hContact, const char *pszGroup);
-
- void servlistPendingAddContactOperation(MCONTACT hContact, LPARAM param, PENDING_CONTACT_CALLBACK callback, DWORD flags);
- void servlistPendingAddGroupOperation(const char *pszGroup, LPARAM param, PENDING_GROUP_CALLBACK callback, DWORD flags);
- int servlistPendingAddContact(MCONTACT hContact, WORD wContactID, WORD wGroupID, LPARAM param, PENDING_CONTACT_CALLBACK callback, int bDoInline, LPARAM operationParam = 0, PENDING_CONTACT_CALLBACK operationCallback = nullptr);
- int servlistPendingAddGroup(const char *pszGroup, WORD wGroupID, LPARAM param, PENDING_GROUP_CALLBACK callback, int bDoInline, LPARAM operationParam = 0, PENDING_GROUP_CALLBACK operationCallback = nullptr);
- void servlistPendingRemoveContact(MCONTACT hContact, WORD wContactID, WORD wGroupID, int nResult);
- void servlistPendingRemoveGroup(const char *pszGroup, WORD wGroupID, int nResult);
- void servlistPendingFlushOperations();
-
- // server-list support functions
- int nJustAddedCount;
- int nJustAddedSize;
- MCONTACT* pdwJustAddedList;
-
- void AddJustAddedContact(MCONTACT hContact);
- BOOL IsContactJustAdded(MCONTACT hContact);
- void FlushJustAddedContacts();
-
- WORD GenerateServerID(int bGroupType, int bFlags, int wCount = 0);
- void ReserveServerID(WORD wID, int bGroupType, int bFlags);
- void FreeServerID(WORD wID, int bGroupType);
- BOOL CheckServerID(WORD wID, unsigned int wCount);
- void FlushServerIDs();
- void LoadServerIDs();
- void StoreServerIDs();
-
- void* collectGroups(int *count);
- void* collectBuddyGroup(WORD wGroupID, int *count);
- char* getServListGroupName(WORD wGroupID);
- void setServListGroupName(WORD wGroupID, const char *szGroupName);
- WORD getServListGroupLinkID(const char *szPath);
- void setServListGroupLinkID(const char *szPath, WORD wGroupID);
- int IsServerGroupsDefined();
- char* getServListGroupCListPath(WORD wGroupId);
- char* getServListUniqueGroupName(const char *szGroupName, int bAlloced);
-
- int __cdecl servlistCreateGroup_gotParentGroup(const char *szGroup, WORD wGroupID, LPARAM param, int nResult);
- int __cdecl servlistCreateGroup_Ready(const char *szGroup, WORD groupID, LPARAM param, int nResult);
- void servlistCreateGroup(const char *szGroupPath, LPARAM param, PENDING_GROUP_CALLBACK callback);
-
- int __cdecl servlistAddContact_gotGroup(const char *szGroup, WORD wGroupID, LPARAM lParam, int nResult);
- int __cdecl servlistAddContact_Ready(MCONTACT hContact, WORD wContactID, WORD wGroupID, LPARAM lParam, int nResult);
- void servlistAddContact(MCONTACT hContact, const char *pszGroup);
-
- int __cdecl servlistRemoveContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult);
- void servlistRemoveContact(MCONTACT hContact);
-
- int __cdecl servlistMoveContact_gotTargetGroup(const char *szGroup, WORD wNewGroupID, LPARAM lParam, int nResult);
- int __cdecl servlistMoveContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult);
- void servlistMoveContact(MCONTACT hContact, const char *pszNewGroup);
-
- int __cdecl servlistUpdateContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult);
- void servlistUpdateContact(MCONTACT hContact);
-
- int __cdecl servlistRenameGroup_Ready(const char *szGroup, WORD wGroupID, LPARAM lParam, int nResult);
- void servlistRenameGroup(char *szGroup, WORD wGroupId, char *szNewGroup);
-
- int __cdecl servlistRemoveGroup_Ready(const char *szGroup, WORD groupID, LPARAM lParam, int nResult);
- void servlistRemoveGroup(const char *szGroup, WORD wGroupId);
-
- void removeGroupPathLinks(WORD wGroupID);
- int getServListGroupLevel(WORD wGroupId);
-
- void resetServContactAuthState(MCONTACT hContact);
-
- void FlushSrvGroupsCache();
- int getCListGroupExists(const char *szGroup);
- int moveContactToCListGroup(MCONTACT hContact, const char *szGroup); /// TODO: this should be DB function
-
- DWORD icq_sendServerItem(DWORD dwCookie, WORD wAction, WORD wGroupId, WORD wItemId, const char *szName, BYTE *pTLVs, size_t nTlvLength, WORD wItemType, DWORD dwOperation, DWORD dwTimeout, void **doubleObject);
- DWORD icq_sendServerContact(MCONTACT hContact, DWORD dwCookie, WORD wAction, WORD wGroupId, WORD wContactId, DWORD dwOperation, DWORD dwTimeout, void **doubleObject);
- DWORD icq_sendSimpleItem(DWORD dwCookie, WORD wAction, DWORD dwUin, char* szUID, WORD wGroupId, WORD wItemId, WORD wItemType, DWORD dwOperation, DWORD dwTimeout);
- DWORD icq_sendServerGroup(DWORD dwCookie, WORD wAction, WORD wGroupId, const char *szName, void *pContent, int cbContent, DWORD dwOperationFlags);
-
- DWORD icq_modifyServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wAction, DWORD dwOperation, WORD wItemId, WORD wType);
- DWORD icq_removeServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wItemId, WORD wType);
- DWORD icq_addServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wItemId, WORD wType);
-
- int __cdecl ServListDbSettingChanged(WPARAM wParam, LPARAM lParam);
- int __cdecl ServListCListGroupChange(WPARAM wParam, LPARAM lParam);
-
- //----| stdpackets.cpp |----------------------------------------------------------
- void icq_sendCloseConnection();
-
- void icq_requestnewfamily(WORD wFamily, void (CIcqProto::*familyhandler)(HNETLIBCONN hConn, char* cookie, size_t cookieLen));
-
- void icq_setidle(bool bIsIdle);
- void icq_setstatus(WORD wStatus, const char *szStatusNote = nullptr);
- DWORD icq_sendGetInfoServ(MCONTACT hContact, DWORD, int);
- DWORD icq_sendGetAimProfileServ(MCONTACT hContact, char *szUid);
- DWORD icq_sendGetAwayMsgServ(MCONTACT hContact, DWORD, int, WORD);
- DWORD icq_sendGetAwayMsgServExt(MCONTACT hContact, DWORD dwUin, char *szUID, int type, WORD wVersion);
- DWORD icq_sendGetAimAwayMsgServ(MCONTACT hContact, char *szUID, int type);
- void icq_sendSetAimAwayMsgServ(const char *szMsg);
-
- void icq_sendFileSendServv7(filetransfer* ft, const char *szFiles);
- void icq_sendFileSendServv8(filetransfer* ft, const char *szFiles, int nAckType);
-
- void icq_sendFileAcceptServ(DWORD dwUin, filetransfer *ft, int nAckType);
- void icq_sendFileAcceptServv7(DWORD dwUin, DWORD TS1, DWORD TS2, DWORD dwCookie, const char *szFiles, const char *szDescr, DWORD dwTotalSize, WORD wPort, BOOL accepted, int nAckType);
- void icq_sendFileAcceptServv8(DWORD dwUin, DWORD TS1, DWORD TS2, DWORD dwCookie, const char *szFiles, const char *szDescr, DWORD dwTotalSize, WORD wPort, BOOL accepted, int nAckType);
-
- void icq_sendFileDenyServ(DWORD dwUin, filetransfer *ft, const char *szReason, int nAckType);
-
- DWORD icq_sendAdvancedSearchServ(BYTE *fieldsBuffer, size_t bufferLen);
- DWORD icq_changeUserPasswordServ(const char *szPassword);
- DWORD icq_changeUserDirectoryInfoServ(const BYTE *pData, size_t wDataLen, BYTE bRequestType);
- void icq_sendGenericContact(DWORD dwUin, const char *szUid, WORD wFamily, WORD wSubType);
- void icq_sendNewContact(DWORD dwUin, const char *szUid);
- void icq_sendRemoveContact(DWORD dwUin, const char *szUid);
- void icq_sendChangeVisInvis(MCONTACT hContact, DWORD dwUin, char* szUID, int list, int add);
- void icq_sendEntireVisInvisList(int);
- void icq_sendAwayMsgReplyServ(DWORD, DWORD, DWORD, WORD, WORD, BYTE, char **);
- void icq_sendAwayMsgReplyServExt(DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wCookie, WORD wVersion, BYTE msgType, char **szMsg);
-
- DWORD icq_sendSMSServ(const char *szPhoneNumber, const char *szMsg);
- void icq_sendMessageCapsServ(DWORD dwUin);
- void icq_sendRevokeAuthServ(DWORD dwUin, char *szUid);
- void icq_sendGrantAuthServ(DWORD dwUin, const char *szUid, const char *szMsg);
- void icq_sendAuthReqServ(DWORD dwUin, char* szUid, const char *szMsg);
- void icq_sendAuthResponseServ(DWORD dwUin, char* szUid,int auth,const wchar_t *szReason);
- void icq_sendYouWereAddedServ(DWORD,DWORD);
-
- DWORD sendDirectorySearchPacket(const BYTE *pSearchData, size_t wDataLen, WORD wPage, BOOL bOnlineUsersOnly);
- DWORD sendTLVSearchPacket(BYTE bType, char* pSearchDataBuf, WORD wSearchType, size_t wInfoLen, BOOL bOnlineUsersOnly);
- void sendOwnerInfoRequest(void);
- DWORD sendUserInfoMultiRequest(BYTE *pRequestData, size_t dataLen, int nItems);
-
- DWORD icq_SendChannel1Message(DWORD dwUin, char *szUID, MCONTACT hContact, char *pszText, cookie_message_data *pCookieData);
- DWORD icq_SendChannel1MessageW(DWORD dwUin, char *szUID, MCONTACT hContact, WCHAR *pszText, cookie_message_data *pCookieData); // UTF-16
- DWORD icq_SendChannel2Message(DWORD dwUin, MCONTACT hContact, const char *szMessage, size_t nBodyLength, WORD wPriority, cookie_message_data *pCookieData, char *szCap);
- DWORD icq_SendChannel2Contacts(DWORD dwUin, char *szUid, MCONTACT hContact, const char *pData, size_t wDataLen, const char *pNames, size_t wNamesLen, cookie_message_data *pCookieData);
- DWORD icq_SendChannel4Message(DWORD dwUin, MCONTACT hContact, BYTE bMsgType, size_t wMsgLen, const char *szMsg, cookie_message_data *pCookieData);
-
- void icq_sendAdvancedMsgAck(DWORD, DWORD, DWORD, WORD, BYTE, BYTE);
- void icq_sendContactsAck(DWORD dwUin, char *szUid, DWORD dwMsgID1, DWORD dwMsgID2);
-
- void icq_sendReverseReq(directconnect *dc, DWORD dwCookie, cookie_message_data *pCookie);
- void icq_sendReverseFailed(directconnect* dc, DWORD dwMsgID1, DWORD dwMsgID2, DWORD dwCookie);
-
- void icq_sendXtrazRequestServ(DWORD dwUin, DWORD dwCookie, char* szBody, size_t nBodyLen, cookie_message_data *pCookieData);
- void icq_sendXtrazResponseServ(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szBody, size_t nBodyLen, int nType);
-
- DWORD SearchByUin(DWORD dwUin);
- DWORD SearchByNames(const char *pszNick, const char *pszFirstName, const char *pszLastName, WORD wPage);
- DWORD SearchByMail(const char *pszEmail);
-
- DWORD icq_searchAimByEmail(const char* pszEmail, DWORD dwSearchId);
-
- void oft_sendFileRequest(DWORD dwUin, char *szUid, oscar_filetransfer *ft, const char *pszFiles, DWORD dwLocalInternalIP);
- void oft_sendFileAccept(DWORD dwUin, char *szUid, oscar_filetransfer *ft);
- void oft_sendFileDeny(DWORD dwUin, char *szUid, oscar_filetransfer *ft);
- void oft_sendFileCancel(DWORD dwUin, char *szUid, oscar_filetransfer *ft);
- void oft_sendFileResponse(DWORD dwUin, char *szUid, oscar_filetransfer *ft, WORD wResponse);
- void oft_sendFileRedirect(DWORD dwUin, char *szUid, oscar_filetransfer *ft, DWORD dwIP, WORD wPort, int bProxy);
-
- //---- | icq_svcs.cpp |----------------------------------------------------------------
- MCONTACT AddToListByUIN(DWORD dwUin, DWORD dwFlags);
- MCONTACT AddToListByUID(const char *szUID, DWORD dwFlags);
-
- void ICQAddRecvEvent(MCONTACT hContact, WORD wType, PROTORECVEVENT* pre, size_t cbBlob, PBYTE pBlob, DWORD flags);
- INT_PTR __cdecl IcqAddCapability(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl IcqCheckCapability(WPARAM wParam, LPARAM lParam);
-
- OBJLIST<ICQ_CUSTOMCAP> CustomCapList;
-
- //----| icq_uploadui.cpp |------------------------------------------------------------
- void ShowUploadContactsDialog(void);
-
- //----| icq_xstatus.cpp |-------------------------------------------------------------
- int m_bHideXStatusUI;
- int m_bHideXStatusMenu;
- int bXStatusExtraIconsReady;
- HANDLE hHookExtraIconsRebuild;
- HANDLE hHookStatusBuild;
- HANDLE hHookExtraIconsApply;
- HGENMENU hXStatusItems[XSTATUS_COUNT + 1];
-
- void InitXStatusItems(BOOL bAllowStatus);
- BYTE getContactXStatus(MCONTACT hContact);
- DWORD sendXStatusDetailsRequest(MCONTACT hContact, int bForced);
- DWORD requestXStatusDetails(MCONTACT hContact, BOOL bAllowDelay);
- HICON getXStatusIcon(int bStatus, UINT flags);
- void setXStatusEx(BYTE bXStatus, BYTE bQuiet);
- void handleXStatusCaps(DWORD dwUIN, char *szUID, MCONTACT hContact, BYTE *caps, int capsize, char *moods, int moodsize);
- void updateServerCustomStatus(int fullUpdate);
-
- //----| icq_xtraz.cpp |---------------------------------------------------------------
- void handleXtrazNotify(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char *szMsg, size_t nMsgLen, BOOL bThruDC);
- void handleXtrazNotifyResponse(MCONTACT hContact, WORD wCookie, char* szMsg);
-
- void handleXtrazInvitation(DWORD dwUin, char *szMsg, BOOL bThruDC);
- void handleXtrazData(DWORD dwUin, char *szMsg, BOOL bThruDC);
-
- DWORD SendXtrazNotifyRequest(MCONTACT hContact, char *szQuery, char *szNotify, int bForced);
- void SendXtrazNotifyResponse(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char *szResponse, size_t nResponseLen, BOOL bThruDC);
-
- //----| init.cpp |--------------------------------------------------------------------
- void UpdateGlobalSettings();
-
- //----| loginpassword.cpp |-----------------------------------------------------------
- void RequestPassword();
-
- //----| oscar_filetransfer.cpp |------------------------------------------------------
- mir_cs oftMutex;
- LIST<basic_filetransfer> m_arFileTransfers;
-
- oscar_filetransfer* CreateOscarTransfer();
- filetransfer *CreateIcqFileTransfer();
- void SafeReleaseFileTransfer(basic_filetransfer **ft);
- oscar_filetransfer* FindOscarTransfer(MCONTACT hContact, DWORD dwID1, DWORD dwID2);
-
- oscar_listener* CreateOscarListener(oscar_filetransfer *ft, NETLIBNEWCONNECTIONPROC_V2 handler);
- void ReleaseOscarListener(oscar_listener **pListener);
-
- void OpenOscarConnection(MCONTACT hContact, oscar_filetransfer *ft, int type);
- void CloseOscarConnection(oscar_connection *oc);
- int CreateOscarProxyConnection(oscar_connection *oc);
-
- int IsValidFileTransfer(basic_filetransfer *ft);
- int IsValidOscarTransfer(basic_filetransfer *ft);
-
- void handleRecvServMsgOFT(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwID1, DWORD dwID2, WORD wCommand);
- void handleRecvServResponseOFT(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, void* ft);
-
- HANDLE oftInitTransfer(MCONTACT hContact, DWORD dwUin, char *szUid, const wchar_t **pszFiles, const wchar_t *szDescription);
- HANDLE oftFileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szPath);
- DWORD oftFileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szReason);
- DWORD oftFileCancel(MCONTACT hContact, HANDLE hTransfer);
- void oftFileResume(oscar_filetransfer *ft, int action, const wchar_t *szFilename);
-
- void sendOscarPacket(oscar_connection *oc, icq_packet *packet);
- void handleOFT2FramePacket(oscar_connection *oc, WORD datatype, BYTE *pBuffer, size_t wLen);
- void sendOFT2FramePacket(oscar_connection *oc, WORD datatype);
-
- void proxy_sendInitTunnel(oscar_connection *oc);
- void proxy_sendJoinTunnel(oscar_connection *oc, WORD wPort);
-
- //----| stdpackets.cpp |--------------------------------------------------------------
- void __cdecl oft_connectionThread(void *otsi);
-
- int oft_handlePackets(oscar_connection *oc, BYTE *buf, size_t len);
- int oft_handleFileData(oscar_connection *oc, BYTE *buf, size_t len);
- int oft_handleProxyData(oscar_connection *oc, BYTE *buf, size_t len);
- void oft_sendFileData(oscar_connection *oc);
- void oft_sendPeerInit(oscar_connection *oc);
- void oft_sendFileReply(DWORD dwUin, char *szUid, oscar_filetransfer *ft, WORD wResult);
-
- //----| upload.cpp |------------------------------------------------------------------
- int StringToListItemId(const char *szSetting,int def);
-
- //----| utilities.cpp |---------------------------------------------------------------
- char* ConvertMsgToUserSpecificAnsi(MCONTACT hContact, const char* szMsg);
-
- template <size_t cbSize>
- char* GetUserStoredPassword(char(&szBuffer)[cbSize]);
- char* GetUserPassword(BOOL bAlways);
- WORD GetMyStatusFlags();
-
- DWORD ReportGenericSendError(MCONTACT hContact, int nType, const char* szErrorMsg);
- void SetCurrentStatus(int nStatus);
-
- void __cdecl ProtocolAckThread(icq_ack_args* pArguments);
- void SendProtoAck(MCONTACT hContact, DWORD dwCookie, int nAckResult, int nAckType, char* pszMessage);
-
- int NetLog_Direct(const char *fmt,...);
- int NetLog_Uni(BOOL bDC, const char *fmt,...);
-
- mir_cs contactsCacheMutex;
- LIST<icq_contacts_cache> contactsCache;
-
- void AddToContactsCache(MCONTACT hContact, DWORD dwUin, const char *szUid);
- void DeleteFromContactsCache(MCONTACT hContact);
- void InitContactsCache();
- void UninitContactsCache();
-
- void AddToSpammerList(DWORD dwUIN);
- BOOL IsOnSpammerList(DWORD dwUIN);
-
- HNETLIBBIND NetLib_BindPort(NETLIBNEWCONNECTIONPROC_V2 pFunc, void* lParam, WORD *pwPort, DWORD *pdwIntIP);
-
- MCONTACT HandleFromCacheByUid(DWORD dwUin, const char *szUid);
- MCONTACT HContactFromUIN(DWORD dwUin, int *Added);
- MCONTACT HContactFromUID(DWORD dwUin, const char *szUid, int *Added);
- MCONTACT HContactFromAuthEvent(MEVENT hEvent);
-
- void ResetSettingsOnListReload();
- void ResetSettingsOnConnect();
- void ResetSettingsOnLoad();
-
- int IsMetaInfoChanged(MCONTACT hContact);
-
- char *setStatusNoteText, *setStatusMoodData;
- void __cdecl SetStatusNoteThread(void *pArguments);
- int SetStatusNote(const char *szStatusNote, DWORD dwDelay, int bForced);
- int SetStatusMood(const char *szMoodData, DWORD dwDelay);
-
- void writeDbInfoSettingTLVStringUtf(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv);
- void writeDbInfoSettingTLVWord(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv);
- void writeDbInfoSettingTLVByte(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv);
- void writeDbInfoSettingTLVDouble(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv);
- void writeDbInfoSettingTLVDate(MCONTACT hContact, const char *szSettingYear, const char *szSettingMonth, const char *szSettingDay, oscar_tlv_chain *chain, WORD wTlv);
- void writeDbInfoSettingTLVBlob(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv);
-
- char** MirandaStatusToAwayMsg(int nStatus);
-
- bool validateStatusMessageRequest(MCONTACT hContact, WORD byMessageType);
-};
-
-struct CMPlugin : public ACCPROTOPLUGIN<CIcqProto>
-{
- CMPlugin();
-
- int Load() override;
- int Unload() override;
-};
-
-#endif
diff --git a/protocols/IcqOscarJ/src/icq_rates.cpp b/protocols/IcqOscarJ/src/icq_rates.cpp
deleted file mode 100644
index 16851055e5..0000000000
--- a/protocols/IcqOscarJ/src/icq_rates.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Rate Management stuff
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-//
-// Rate Level 1 Management
-/////////////////////////////
-
-rates::rates(CIcqProto *ppro, BYTE *pBuffer, size_t wLen)
-{
- nGroups = 0;
- memset(&groups, 0, MAX_RATES_GROUP_COUNT * sizeof(rates_group));
- this->ppro = ppro;
-
- // Parse Rate Data Block
- WORD wCount;
- unpackWord(&pBuffer, &wCount);
- wLen -= 2;
-
- if (wCount > MAX_RATES_GROUP_COUNT) {
- // just sanity check
- ppro->debugLogA("Rates: Error: Data packet contains too many rate groups!");
- wCount = MAX_RATES_GROUP_COUNT;
- }
-
- nGroups = wCount;
- // Parse Group details
- int i;
- for (i = 0; i < wCount; i++) {
- rates_group *pGroup = &groups[i];
-
- if (wLen >= 35) {
- pBuffer += 2; // Group ID
- unpackDWord(&pBuffer, &pGroup->dwWindowSize);
- unpackDWord(&pBuffer, &pGroup->dwClearLevel);
- unpackDWord(&pBuffer, &pGroup->dwAlertLevel);
- unpackDWord(&pBuffer, &pGroup->dwLimitLevel);
- pBuffer += 8;
- unpackDWord(&pBuffer, &pGroup->dwMaxLevel);
- pBuffer += 5;
- wLen -= 35;
- }
- else { // packet broken, put some basic defaults
- pGroup->dwWindowSize = 10;
- pGroup->dwMaxLevel = 5000;
- }
- pGroup->rCurrentLevel = pGroup->dwMaxLevel;
- }
- // Parse Group associated pairs
- for (i = 0; i < wCount; i++) {
- rates_group *pGroup = &groups[i];
-
- if (wLen < 4)
- break;
-
- pBuffer += 2; // Group ID
- WORD wNum;
- unpackWord(&pBuffer, &wNum);
- wLen -= 4;
- if (wLen < (size_t)wNum * 4)
- break;
-
- pGroup->nPairs = wNum;
- pGroup->pPairs = (WORD*)SAFE_MALLOC(wNum * 4);
- for (size_t n = 0; n < (size_t)wNum * 2; n++) {
- WORD wItem;
- unpackWord(&pBuffer, &wItem);
- pGroup->pPairs[n] = wItem;
- }
-
- wLen -= wNum * 4;
- }
-}
-
-rates::~rates()
-{
- for (int i = 0; i < nGroups; i++)
- SAFE_FREE((void**)&groups[i].pPairs);
-
- nGroups = 0;
-}
-
-WORD rates::getGroupFromSNAC(WORD wFamily, WORD wCommand)
-{
- if (this) {
- for (int i = 0; i < nGroups; i++) {
- rates_group* pGroup = &groups[i];
-
- for (int j = 0; j < 2 * pGroup->nPairs; j += 2) {
- if (pGroup->pPairs[j] == wFamily && pGroup->pPairs[j + 1] == wCommand) { // we found the group
- return (WORD)(i + 1);
- }
- }
- }
- // Legacy ICQ server
- }
-
- return 0; // Failure
-}
-
-WORD rates::getGroupFromPacket(icq_packet *pPacket)
-{
- if (this) {
- if (pPacket->nChannel == ICQ_DATA_CHAN && pPacket->wLen >= 0x10) {
- WORD wFamily, wCommand;
- BYTE *pBuf = pPacket->pData + 6;
-
- unpackWord(&pBuf, &wFamily);
- unpackWord(&pBuf, &wCommand);
-
- return getGroupFromSNAC(wFamily, wCommand);
- }
- }
- return 0;
-}
-
-rates_group* rates::getGroup(WORD wGroup)
-{
- if (this && wGroup && wGroup <= nGroups)
- return &groups[wGroup - 1];
-
- return nullptr;
-}
-
-int rates::getNextRateLevel(WORD wGroup)
-{
- rates_group *pGroup = getGroup(wGroup);
-
- if (pGroup) {
- int nLevel = pGroup->rCurrentLevel*(pGroup->dwWindowSize - 1) / pGroup->dwWindowSize + (GetTickCount() - pGroup->tCurrentLevel) / pGroup->dwWindowSize;
-
- return nLevel < (int)pGroup->dwMaxLevel ? nLevel : pGroup->dwMaxLevel;
- }
- return -1; // Failure
-}
-
-int rates::getDelayToLimitLevel(WORD wGroup, int nLevel)
-{
- rates_group *pGroup = getGroup(wGroup);
-
- if (pGroup)
- return (getLimitLevel(wGroup, nLevel) - pGroup->rCurrentLevel)*pGroup->dwWindowSize + pGroup->rCurrentLevel;
-
- return 0; // Failure
-}
-
-void rates::packetSent(icq_packet *pPacket)
-{
- if (this) {
- WORD wGroup = getGroupFromPacket(pPacket);
-
- if (wGroup)
- updateLevel(wGroup, getNextRateLevel(wGroup));
- }
-}
-
-void rates::updateLevel(WORD wGroup, int nLevel)
-{
- rates_group *pGroup = getGroup(wGroup);
-
- if (pGroup) {
- pGroup->rCurrentLevel = nLevel;
- pGroup->tCurrentLevel = GetTickCount();
-
- ppro->debugLogA("Rates: New level %d for #%d", nLevel, wGroup);
- }
-}
-
-int rates::getLimitLevel(WORD wGroup, int nLevel)
-{
- rates_group *pGroup = getGroup(wGroup);
-
- if (pGroup) {
- switch (nLevel) {
- case RML_CLEAR:
- return pGroup->dwClearLevel;
-
- case RML_ALERT:
- return pGroup->dwAlertLevel;
-
- case RML_LIMIT:
- return pGroup->dwLimitLevel;
-
- case RML_IDLE_10:
- return pGroup->dwClearLevel + ((pGroup->dwMaxLevel - pGroup->dwClearLevel) / 10);
-
- case RML_IDLE_30:
- return pGroup->dwClearLevel + (3 * (pGroup->dwMaxLevel - pGroup->dwClearLevel) / 10);
-
- case RML_IDLE_50:
- return pGroup->dwClearLevel + ((pGroup->dwMaxLevel - pGroup->dwClearLevel) / 2);
-
- case RML_IDLE_70:
- return pGroup->dwClearLevel + (7 * (pGroup->dwMaxLevel - pGroup->dwClearLevel) / 10);
- }
- }
- return 9999; // some high number - without rates we allow anything
-}
-
-void rates::initAckPacket(icq_packet *pPacket)
-{
- serverPacketInit(pPacket, 10 + nGroups * sizeof(WORD));
- packFNACHeader(pPacket, ICQ_SERVICE_FAMILY, ICQ_CLIENT_RATE_ACK);
- for (WORD wGroup = 1; wGroup <= nGroups; wGroup++)
- packWord(pPacket, wGroup);
-}
-
-//
-// Rate Level 2 Management
-/////////////////////////////
-
-rates_queue_item::rates_queue_item(CIcqProto *ppro, WORD wGroup) : bCreated(FALSE), dwUin(0), szUid(nullptr)
-{
- this->ppro = ppro;
- this->wGroup = wGroup;
-}
-
-rates_queue_item::~rates_queue_item()
-{
- if (bCreated) {
- SAFE_FREE(&szUid);
- bCreated = FALSE;
- }
-}
-
-BOOL rates_queue_item::isEqual(rates_queue_item *pItem)
-{
- // the same event (equal address of _vftable) for the same contact
- return (pItem->hContact == this->hContact) && (*(void**)pItem == *(void**)this);
-}
-
-rates_queue_item* rates_queue_item::copyItem(rates_queue_item *pDest)
-{
- if (!pDest)
- pDest = new rates_queue_item(ppro, wGroup);
-
- pDest->hContact = hContact;
- pDest->dwUin = dwUin;
- pDest->szUid = dwUin ? null_strdup(szUid) : nullptr;
- pDest->bCreated = TRUE;
-
- return pDest;
-}
-
-void rates_queue_item::execute()
-{
- ppro->debugLogA("Rates: Error executing abstract event.");
-}
-
-BOOL rates_queue_item::isOverRate(int nLevel)
-{
- mir_cslock l(ppro->m_ratesMutex);
-
- if (ppro->m_rates)
- return ppro->m_rates->getNextRateLevel(wGroup) < ppro->m_rates->getLimitLevel(wGroup, nLevel);
-
- return FALSE;
-}
-
-rates_queue::rates_queue(CIcqProto *_ppro, const char *_descr, int nLimitLevel, int nWaitLevel, int nDuplicates) :
- lstPending(1)
-{
- ppro = _ppro;
- szDescr = _descr;
- limitLevel = nLimitLevel;
- waitLevel = nWaitLevel;
- duplicates = nDuplicates;
-}
-
-rates_queue::~rates_queue()
-{
- cleanup();
-}
-
-static void rateDelayThread(rates_queue *pQueue)
-{
- Thread_SetName("ICQ: rateDelayThread");
- pQueue->handleDelay();
-}
-
-void rates_queue::initDelay(int nDelay)
-{
- ppro->debugLogA("Rates: Delay %dms", nDelay);
-
- scheduledDelay = nDelay;
- mir_forkThread<rates_queue>(rateDelayThread, this);
-}
-
-void rates_queue::handleDelay()
-{
- SleepEx(scheduledDelay, TRUE);
-
- if (!Miranda_IsTerminated())
- processQueue();
-}
-
-void rates_queue::cleanup()
-{
- mir_cslock l(csLists);
- for (auto &it : lstPending)
- delete it;
- lstPending.destroy();
-}
-
-void rates_queue::processQueue()
-{
- if (!ppro->icqOnline())
- return;
-
- // take from queue, execute
- mir_cslockfull l(csLists);
- if (lstPending.getCount() == 0)
- return;
-
- rates_queue_item *item = lstPending[0];
- {
- mir_cslockfull rlck(ppro->m_ratesMutex);
- if (item->isOverRate(limitLevel)) { // the rate is higher, keep sleeping
- int nDelay = ppro->m_rates->getDelayToLimitLevel(item->wGroup, ppro->m_rates->getLimitLevel(item->wGroup, waitLevel));
-
- l.unlock();
- rlck.unlock();
- if (nDelay < 10) nDelay = 10;
- initDelay(nDelay);
- return;
- }
- }
-
- lstPending.remove(int(0));
- bool bSetupTimer = lstPending.getCount() != 0;
-
- l.unlock();
-
- if (ppro->icqOnline()) {
- ppro->debugLogA("Rates: Resuming %s.", szDescr);
- item->execute();
- }
- else ppro->debugLogA("Rates: Discarding %s.", szDescr);
-
- if (bSetupTimer) { // in queue remained some items, setup timer
- int nDelay;
- {
- mir_cslockfull rlck(ppro->m_ratesMutex);
- nDelay = ppro->m_rates->getDelayToLimitLevel(item->wGroup, waitLevel);
- }
-
- if (nDelay < 10) nDelay = 10;
- initDelay(nDelay);
- }
- delete item;
-}
-
-void rates_queue::putItem(rates_queue_item *pItem, int nMinDelay)
-{
- if (!ppro->icqOnline())
- return;
-
- ppro->debugLogA("Rates: Delaying %s.", szDescr);
- {
- mir_cslock l(csLists);
-
- auto T = lstPending.rev_iter();
- for (auto &it : T) {
- if (it->isEqual(pItem)) {
- if (duplicates == 1) // keep existing, ignore new
- return;
-
- if (duplicates == -1) { // discard existing, append new item
- delete it;
- lstPending.remove(T.indexOf(&it));
- }
- }
- }
-
- lstPending.insert(pItem->copyItem());
- }
-
- if (lstPending.getCount() != 1)
- return;
-
- // queue was empty setup timer
- int nDelay;
- {
- mir_cslock rlck(ppro->m_ratesMutex);
- nDelay = ppro->m_rates->getDelayToLimitLevel(pItem->wGroup, waitLevel);
- }
-
- if (nDelay < 10) nDelay = 10;
- if (nDelay < nMinDelay) nDelay = nMinDelay;
- initDelay(nDelay);
-}
-
-int CIcqProto::handleRateItem(rates_queue_item *item, int nQueueType, int nMinDelay, BOOL bAllowDelay)
-{
- rates_queue *pQueue = nullptr;
- {
- mir_cslock rlck(m_ratesMutex);
- switch (nQueueType) {
- case RQT_REQUEST:
- pQueue = m_ratesQueue_Request;
- break;
- case RQT_RESPONSE:
- pQueue = m_ratesQueue_Response;
- break;
- }
-
- if (pQueue) {
- if (bAllowDelay && (item->isOverRate(pQueue->waitLevel) || nMinDelay)) {
- // limit reached or min delay configured, add to queue
- pQueue->putItem(item, nMinDelay);
- return 1;
- }
- }
- }
-
- item->execute();
- return 0;
-}
diff --git a/protocols/IcqOscarJ/src/icq_rates.h b/protocols/IcqOscarJ/src/icq_rates.h
deleted file mode 100644
index addd97725c..0000000000
--- a/protocols/IcqOscarJ/src/icq_rates.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Rate management
-// -----------------------------------------------------------------------------
-
-#ifndef __ICQ_RATES_H
-#define __ICQ_RATES_H
-
-#define MAX_RATES_GROUP_COUNT 5
-
-struct rates_group
-{
- DWORD dwWindowSize;
- DWORD dwClearLevel;
- DWORD dwAlertLevel;
- DWORD dwLimitLevel;
- DWORD dwMaxLevel;
-
- // current level
- int rCurrentLevel;
- int tCurrentLevel;
-
- // links
- WORD *pPairs;
- int nPairs;
-};
-
-struct rates : public MZeroedObject
-{
-private:
- CIcqProto * ppro;
- int nGroups;
- rates_group groups[MAX_RATES_GROUP_COUNT];
-
- rates_group *getGroup(WORD wGroup);
-public:
- rates(CIcqProto *ppro, BYTE *pBuffer, size_t wLen);
- ~rates();
-
- WORD getGroupFromSNAC(WORD wFamily, WORD wCommand);
- WORD getGroupFromPacket(icq_packet *pPacket);
-
- int getLimitLevel(WORD wGroup, int nLevel);
- int getDelayToLimitLevel(WORD wGroup, int nLevel);
- int getNextRateLevel(WORD wGroup);
-
- void packetSent(icq_packet *pPacket);
- void updateLevel(WORD wGroup, int nLevel);
-
- void initAckPacket(icq_packet *pPacket);
-};
-
-#define RML_CLEAR 0x01
-#define RML_ALERT 0x02
-#define RML_LIMIT 0x03
-#define RML_IDLE_10 0x10
-#define RML_IDLE_30 0x11
-#define RML_IDLE_50 0x12
-#define RML_IDLE_70 0x13
-
-// Rates - Level 2
-
-// queue types
-#define RQT_DEFAULT 0 // standard - pushes all items without much delay
-#define RQT_REQUEST 1 // request - pushes only first item on duplicity
-#define RQT_RESPONSE 2 // response - pushes only last item on duplicity
-
-//
-// generic queue item
-//
-struct rates_queue_item : public MZeroedObject
-{
- friend class rates_queue;
-protected:
- CIcqProto * ppro;
- BOOL bCreated;
- WORD wGroup;
-
- virtual BOOL isEqual(rates_queue_item *pItem);
- virtual rates_queue_item* copyItem(rates_queue_item *pDest = nullptr);
-public:
- rates_queue_item(CIcqProto *ppro, WORD wGroup);
- virtual ~rates_queue_item();
-
- BOOL isOverRate(int nLevel);
-
- virtual void execute();
-
- MCONTACT hContact;
- DWORD dwUin;
- char *szUid;
-};
-
-//
-// generic item queue (FIFO)
-//
-class rates_queue : public MZeroedObject
-{
- CIcqProto *ppro;
- const char *szDescr;
- int duplicates;
- int scheduledDelay;
-
- mir_cs csLists; // we need to be thread safe
- LIST<rates_queue_item> lstPending;
-
-protected:
- void cleanup();
- void initDelay(int nDelay);
- void processQueue();
-
-public:
- rates_queue(CIcqProto *ppro, const char *szDescr, int nLimitLevel, int nWaitLevel, int nDuplicates);
- ~rates_queue();
-
- void putItem(rates_queue_item *pItem, int nMinDelay);
- void handleDelay();
-
- int limitLevel; // RML_*
- int waitLevel;
-};
-
-
-#endif /* __ICQ_RATES_H */
diff --git a/protocols/IcqOscarJ/src/icq_server.cpp b/protocols/IcqOscarJ/src/icq_server.cpp
deleted file mode 100644
index 00ada57843..0000000000
--- a/protocols/IcqOscarJ/src/icq_server.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Manages main server connection, low-level communication
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void icq_newConnectionReceived(HNETLIBCONN hNewConnection, DWORD dwRemoteIP, void *pExtra);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// ICQ Server thread
-
-void __cdecl CIcqProto::ServerThread(serverthread_start_info *infoParam)
-{
- Thread_SetName("ICQ: ServerThread");
-
- serverthread_info info = { 0 };
- info.isLoginServer = info.bReinitRecver = true;
- info.wAuthKeyLen = infoParam->wPassLen;
- null_strcpy((char*)info.szAuthKey, infoParam->szPass, info.wAuthKeyLen);
- // store server port
- info.wServerPort = infoParam->nloc.wPort;
-
- srand(time(0));
-
- ResetSettingsOnConnect();
-
- // Connect to the login server
- debugLogA("Authenticating to server");
- {
- NETLIBOPENCONNECTION nloc = infoParam->nloc;
- nloc.timeout = 6;
- if (m_bGatewayMode)
- nloc.flags |= NLOCF_HTTPGATEWAY;
-
- hServerConn = NetLib_OpenConnection(m_hNetlibUser, nullptr, &nloc);
-
- SAFE_FREE((void**)&nloc.szHost);
- SAFE_FREE((void**)&infoParam);
-
- if (hServerConn && m_bSecureConnection) {
- if (!Netlib_StartSsl(hServerConn, nullptr)) {
- icq_LogMessage(LOG_ERROR, LPGEN("Unable to connect to ICQ login server, SSL could not be negotiated"));
- SetCurrentStatus(ID_STATUS_OFFLINE);
- NetLib_CloseConnection(&hServerConn, TRUE);
- return;
- }
- }
- }
-
- // Login error
- if (hServerConn == nullptr) {
- DWORD dwError = GetLastError();
-
- SetCurrentStatus(ID_STATUS_OFFLINE);
-
- icq_LogUsingErrorCode(LOG_ERROR, dwError, LPGEN("Unable to connect to ICQ login server"));
- return;
- }
-
- // Initialize direct connection ports
- DWORD dwInternalIP;
- BYTE bConstInternalIP = getByte("ConstRealIP", 0);
-
- info.hDirectBoundPort = NetLib_BindPort(icq_newConnectionReceived, this, &wListenPort, &dwInternalIP);
- if (!info.hDirectBoundPort) {
- icq_LogUsingErrorCode(LOG_WARNING, GetLastError(), LPGEN("Miranda was unable to allocate a port to listen for direct peer-to-peer connections between clients. You will be able to use most of the ICQ network without problems but you may be unable to send or receive files.\n\nIf you have a firewall this may be blocking Miranda, in which case you should configure your firewall to leave some ports open and tell Miranda which ports to use in Options -> Network -> ICQ client-to-client connections."));
- wListenPort = 0;
- if (!bConstInternalIP)
- delSetting("RealIP");
- }
- else if (!bConstInternalIP)
- setDword("RealIP", dwInternalIP);
-
- // Initialize rate limiting queues
- {
- mir_cslock l(m_ratesMutex);
- m_ratesQueue_Request = new rates_queue(this, "request", RML_IDLE_30, RML_IDLE_50, 1);
- m_ratesQueue_Response = new rates_queue(this, "response", RML_IDLE_10, RML_IDLE_30, -1);
- }
-
- StartKeepAlive(&info);
-
- // This is the "infinite" loop that receives the packets from the ICQ server
- NETLIBPACKETRECVER packetRecv;
- info.hPacketRecver = Netlib_CreatePacketReceiver(hServerConn, 0x2400);
-
- while (serverThreadHandle) {
- if (info.bReinitRecver) { // we reconnected, reinit struct
- info.bReinitRecver = false;
- memset(&packetRecv, 0, sizeof(packetRecv));
- packetRecv.dwTimeout = 1000;
- }
-
- int recvResult = Netlib_GetMorePackets(info.hPacketRecver, &packetRecv);
- if (recvResult == 0) {
- debugLogA("Clean closure of server socket");
- break;
- }
-
- if (recvResult == SOCKET_ERROR) {
- DWORD dwError = GetLastError();
- if (dwError == ERROR_TIMEOUT) {
- if (m_iDesiredStatus == ID_STATUS_OFFLINE)
- break;
-
- CheckKeepAlive(&info);
- continue;
- }
- if (dwError == WSAESHUTDOWN) // ok, we're going offline
- break;
-
- debugLogA("Abortive closure of server socket, error: %d", dwError);
- break;
- }
-
- // Deal with the packet
- CheckKeepAlive(&info);
- packetRecv.bytesUsed = handleServerPackets(packetRecv.buffer, packetRecv.bytesAvailable, &info);
- }
- serverThreadHandle = nullptr;
-
- // Time to shutdown
- debugLogA("Closing server connections...");
- NetLib_CloseConnection(&hServerConn, TRUE);
-
- // Close the packet receiver (connection may still be open)
- NetLib_SafeCloseHandle(&info.hPacketRecver);
-
- // Close DC port
- Netlib_CloseHandle(info.hDirectBoundPort);
- info.hDirectBoundPort = nullptr;
-
- // disable auto info-update thread
- icq_EnableUserLookup(FALSE);
-
- if (m_iStatus != ID_STATUS_OFFLINE && m_iDesiredStatus != ID_STATUS_OFFLINE) {
- if (!info.bLoggedIn)
- icq_LogMessage(LOG_FATAL, LPGEN("Connection failed.\nLogin sequence failed for unknown reason.\nTry again later."));
-
- // set flag indicating we were kicked out
- m_bConnectionLost = true;
-
- SetCurrentStatus(ID_STATUS_OFFLINE);
- }
-
- // signal keep-alive thread to stop
- StopKeepAlive(&info);
-
- // Close all open DC connections
- CloseContactDirectConns(NULL);
-
- // Close avatar connection if any
- StopAvatarThread();
-
- // Offline all contacts
- for (auto &hContact : AccContacts()) {
- if (getContactStatus(hContact) == ID_STATUS_OFFLINE)
- continue;
-
- setWord(hContact, "Status", ID_STATUS_OFFLINE);
-
- DWORD dwUIN;
- uid_str szUID;
- if (!getContactUid(hContact, &dwUIN, &szUID)) {
- char tmp = 0;
- handleXStatusCaps(dwUIN, szUID, hContact, (BYTE*)&tmp, 0, &tmp, 0);
- }
- }
-
- setDword("LogonTS", 0); // clear logon time
-
- servlistPendingFlushOperations(); // clear pending operations list
-
- // release rates queues
- {
- mir_cslock l(m_ratesMutex);
- delete m_ratesQueue_Request; m_ratesQueue_Request = nullptr;
- delete m_ratesQueue_Response; m_ratesQueue_Response = nullptr;
- delete m_rates; m_rates = nullptr;
- }
-
- FlushServerIDs(); // clear server IDs list
-
- debugLogA("%s thread ended.", "Server");
-}
-
-void CIcqProto::icq_serverDisconnect()
-{
- if (!hServerConn)
- return;
-
- debugLogA("Server shutdown requested");
- Netlib_Shutdown(hServerConn);
-
- debugLogA("Dropping server thread");
- if (serverThreadHandle) {
- debugLogA("Closing server thread handle: %08p", serverThreadHandle);
- CloseHandle(serverThreadHandle);
- serverThreadHandle = nullptr;
- }
-
- SetCurrentStatus(ID_STATUS_OFFLINE);
-}
-
-int CIcqProto::handleServerPackets(BYTE *buf, int len, serverthread_info *info)
-{
- BYTE channel;
- WORD sequence;
- WORD datalen;
- int bytesUsed = 0;
-
- while (len > 0) {
- if (info->bReinitRecver)
- break;
-
- // All FLAPS begin with 0x2a
- if (*buf++ != FLAP_MARKER)
- break;
-
- if (len < 6)
- break;
-
- unpackByte(&buf, &channel);
- unpackWord(&buf, &sequence);
- unpackWord(&buf, &datalen);
-
- if (len < 6 + datalen)
- break;
-
- debugLogA("Server FLAP: Channel %u, Seq %u, Length %u bytes", channel, sequence, datalen);
-
- switch (channel) {
- case ICQ_LOGIN_CHAN:
- handleLoginChannel(buf, datalen, info);
- break;
-
- case ICQ_DATA_CHAN:
- handleDataChannel(buf, datalen, info);
- break;
-
- case ICQ_ERROR_CHAN:
- handleErrorChannel(buf, datalen);
- break;
-
- case ICQ_CLOSE_CHAN:
- handleCloseChannel(buf, datalen, info);
- break; // we need this for walking thru proxy
-
- case ICQ_PING_CHAN:
- handlePingChannel(buf, datalen);
- break;
-
- default:
- debugLogA("Warning: Unhandled Server FLAP Channel: Channel %u, Seq %u, Length %u bytes", channel, sequence, datalen);
- break;
- }
-
- /* Increase pointers so we can check for more FLAPs */
- buf += datalen;
- len -= (datalen + 6);
- bytesUsed += (datalen + 6);
- }
-
- return bytesUsed;
-}
-
-
-void CIcqProto::sendServPacket(icq_packet *pPacket)
-{
- // make sure to have the connection handle
- mir_cslockfull l(connectionHandleMutex);
-
- if (hServerConn) {
- // This critsec makes sure that the sequence order doesn't get screwed up
- int nSendResult;
- {
- mir_cslock slck(localSeqMutex);
-
- // :IMPORTANT:
- // The FLAP sequence must be a WORD. When it reaches 0xFFFF it should wrap to
- // 0x0000, otherwise we'll get kicked by server.
- wLocalSequence++;
-
- // Pack sequence number
- pPacket->pData[2] = ((wLocalSequence & 0xff00) >> 8);
- pPacket->pData[3] = (wLocalSequence & 0x00ff);
-
- nSendResult = Netlib_Send(hServerConn, (const char *)pPacket->pData, pPacket->wLen, 0);
- }
- l.unlock();
-
- // Send error
- if (nSendResult == SOCKET_ERROR) {
- DWORD dwErrorCode = GetLastError();
- if (dwErrorCode != WSAESHUTDOWN)
- icq_LogUsingErrorCode(LOG_ERROR, GetLastError(), LPGEN("Your connection with the ICQ server was abortively closed"));
- icq_serverDisconnect();
- }
- else { // Rates management
- mir_cslock r(m_ratesMutex);
- m_rates->packetSent(pPacket);
- }
- }
- else debugLogA("Error: Failed to send packet (no connection)");
-
- SAFE_FREE((void**)&pPacket->pData);
-}
-
-
-void __cdecl CIcqProto::SendPacketAsyncThread(icq_packet* pkt)
-{
- Thread_SetName("ICQ: SendPacketAsyncThread");
- sendServPacket(pkt);
- SAFE_FREE((void**)&pkt);
-}
-
-
-void CIcqProto::sendServPacketAsync(icq_packet *packet)
-{
- icq_packet *pPacket;
-
- pPacket = (icq_packet*)SAFE_MALLOC(sizeof(icq_packet)); // This will be freed in the new thread
- memcpy(pPacket, packet, sizeof(icq_packet));
-
- ForkThread((MyThreadFunc)&CIcqProto::SendPacketAsyncThread, pPacket);
-}
-
-
-int CIcqProto::IsServerOverRate(WORD wFamily, WORD wCommand, int nLevel)
-{
- mir_cslock l(m_ratesMutex);
-
- if (m_rates) {
- WORD wGroup = m_rates->getGroupFromSNAC(wFamily, wCommand);
-
- // check if the rate is not over specified level
- if (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, nLevel))
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// ICQ Server thread
-
-void CIcqProto::icq_login(const char* szPassword)
-{
- DWORD dwUin = getContactUin(NULL);
- serverthread_start_info* stsi = (serverthread_start_info*)SAFE_MALLOC(sizeof(serverthread_start_info));
-
- // Server host name
- char szServer[MAX_PATH];
- if (getSettingStringStatic(NULL, "OscarServer", szServer, MAX_PATH))
- stsi->nloc.szHost = null_strdup(m_bSecureConnection ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST);
- else
- stsi->nloc.szHost = null_strdup(szServer);
-
- // Server port
- stsi->nloc.wPort = getWord("OscarPort", m_bSecureConnection ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT);
- if (stsi->nloc.wPort == 0)
- stsi->nloc.wPort = RandRange(1024, 65535);
-
- // User password
- stsi->wPassLen = mir_strlen(szPassword);
- null_strcpy(stsi->szPass, szPassword, stsi->wPassLen);
-
- // Randomize sequence
- wLocalSequence = generate_flap_sequence();
-
- m_dwLocalUIN = dwUin;
-
- // Initialize members
- m_avatarsConnectionPending = TRUE;
-
- serverThreadHandle = ForkThreadEx((MyThreadFunc)&CIcqProto::ServerThread, stsi, &serverThreadId);
-}
diff --git a/protocols/IcqOscarJ/src/icq_server.h b/protocols/IcqOscarJ/src/icq_server.h
deleted file mode 100644
index 2cc012f80f..0000000000
--- a/protocols/IcqOscarJ/src/icq_server.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Declarations for server thread
-// -----------------------------------------------------------------------------
-
-#ifndef __ICQ_SERVER_H
-#define __ICQ_SERVER_H
-
-struct serverthread_start_info
-{
- NETLIBOPENCONNECTION nloc;
- size_t wPassLen;
- char szPass[128];
-};
-
-struct serverthread_info
-{
- BYTE szAuthKey[20];
- size_t wAuthKeyLen;
- WORD wServerPort;
- char *newServer;
- BYTE *cookieData;
- int cookieDataLen;
- int newServerSSL;
- time_t tmPing; // timestamp of the next ping
-
- bool isLoginServer;
- bool isMigrating;
- bool isNewServerReady;
- bool bLoggedIn;
- bool bReinitRecver;
- bool bMyAvatarInited;
-
- HANDLE hPacketRecver;
- HNETLIBBIND hDirectBoundPort;
-};
-
-#endif /* __ICQ_SERVER_H */
diff --git a/protocols/IcqOscarJ/src/icq_servlist.cpp b/protocols/IcqOscarJ/src/icq_servlist.cpp
deleted file mode 100644
index ee70e8de8a..0000000000
--- a/protocols/IcqOscarJ/src/icq_servlist.cpp
+++ /dev/null
@@ -1,2349 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Functions that handles list of used server IDs, sends low-level packets for SSI information
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-// SERVER-LIST UPDATE BOARD
-//
-
-void CIcqProto::servlistBeginOperation(int operationCount, int bImport)
-{
- // check if we should send operation begin packet
- if (operationCount) {
- if (!servlistEditCount)
- icq_sendServerBeginOperation(bImport);
-
- // update count of active operations
- servlistEditCount += operationCount;
- debugLogA("Server-List: Begin operation processed (%d operations active)", servlistEditCount);
- }
-}
-
-void CIcqProto::servlistEndOperation(int operationCount)
-{
- if (operationCount) {
- if (operationCount > servlistEditCount) { // sanity check
- debugLogA("Error: Server-List End operation is not paired!");
- operationCount = servlistEditCount;
- }
- // update count of active operations
- servlistEditCount -= operationCount;
- // check if we should send operation end packet
- if (!servlistEditCount)
- icq_sendServerEndOperation();
-
- debugLogA("Server-List: End operation processed (%d operations active)", servlistEditCount);
- }
-}
-
-void __cdecl CIcqProto::servlistQueueThread(void *param)
-{
- debugLogA("Server-List: Starting Update board.");
- Thread_SetName("ICQ: servlistQueueThread");
-
- int *queueState = (int*)param;
- SleepEx(50, FALSE);
-
- // handle server-list requests queue
- mir_cslockfull l(servlistQueueMutex);
-
- while (servlistQueueCount) {
- ssiqueueditems* pItem = nullptr;
- int bItemDouble;
- WORD wItemAction;
- icq_packet groupPacket = { 0 };
- icq_packet groupPacket2 = { 0 };
- int nEndOperations;
-
- // first check if the state is calm
- while (*queueState) {
- int i;
- time_t tNow = time(0);
- int bFound = FALSE;
-
- for (i = 0; i < servlistQueueCount; i++) { // check if we do not have some expired items to handle, otherwise keep sleeping
- if ((servlistQueueList[i]->tAdded + servlistQueueList[i]->dwTimeout) < tNow) { // got expired item, stop sleep even when changes goes on
- bFound = TRUE;
- break;
- }
- }
- if (bFound) break;
- // reset queue state, keep sleeping
- *queueState = FALSE;
- l.unlock();
- SleepEx(100, TRUE);
- l.lock();
- }
- if (!icqOnline()) { // do not try to send packets if offline
- l.unlock();
- SleepEx(100, TRUE);
- l.lock();
- continue;
- }
-
- debugLogA("Server-List: %d items in queue.", servlistQueueCount);
-
- // take the oldest item (keep the board FIFO)
- pItem = servlistQueueList[0]; // take first (queue contains at least one item here)
- wItemAction = (WORD)(pItem->pItems[0]->dwOperation & SSOF_ACTIONMASK);
- bItemDouble = pItem->pItems[0]->dwOperation & SSOG_DOUBLE;
-
- // check item rate - too high -> sleep
- {
- mir_cslockfull rlck(m_ratesMutex);
-
- WORD wRateGroup = m_rates->getGroupFromSNAC(ICQ_LISTS_FAMILY, wItemAction);
- int nRateLevel = bItemDouble ? RML_IDLE_30 : RML_IDLE_10;
-
- while (m_rates->getNextRateLevel(wRateGroup) < m_rates->getLimitLevel(wRateGroup, nRateLevel)) { // the rate is higher, keep sleeping
- int nDelay = m_rates->getDelayToLimitLevel(wRateGroup, nRateLevel);
-
- rlck.unlock();
- // do not keep the queue frozen
- l.unlock();
- if (nDelay < 10)
- nDelay = 10;
-
- debugLogA("Server-List: Delaying %dms [Rates]", nDelay);
-
- SleepEx(nDelay, FALSE);
- // check if the rate is now ok
- l.lock();
- rlck.lock();
- }
- }
-
- {
- // setup group packet(s) & cookie
- int totalSize = 0;
- int i;
- cookie_servlist_action *pGroupCookie;
- DWORD dwGroupCookie;
- // determine the total size of the packet
- for (i = 0; i < pItem->nItems; i++)
- totalSize += pItem->pItems[i]->packet.wLen - 0x10;
-
- // process begin & end operation flags
- {
- int bImportOperation = FALSE;
- int nBeginOperations = 0;
-
- nEndOperations = 0;
- for (i = 0; i < pItem->nItems; i++) { // collect begin & end operation flags
- if (pItem->pItems[i]->dwOperation & SSOF_BEGIN_OPERATION)
- nBeginOperations++;
- if (pItem->pItems[i]->dwOperation & SSOF_END_OPERATION)
- nEndOperations++;
- // check if the operation is import
- if (pItem->pItems[i]->dwOperation & SSOF_IMPORT_OPERATION)
- bImportOperation = TRUE;
- }
- // really begin operation if requested
- if (nBeginOperations)
- servlistBeginOperation(nBeginOperations, bImportOperation);
- }
-
- if (pItem->nItems > 1) { // pack all packet's data, create group cookie
- pGroupCookie = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- pGroupCookie->dwAction = SSA_ACTION_GROUP;
- pGroupCookie->dwGroupCount = pItem->nItems;
- pGroupCookie->pGroupItems = (cookie_servlist_action**)SAFE_MALLOC(pItem->nItems * sizeof(cookie_servlist_action*));
- for (i = 0; i < pItem->nItems; i++) { // build group cookie data - assign cookies datas
- pGroupCookie->pGroupItems[i] = pItem->pItems[i]->cookie;
- // release the separate cookie id
- FreeCookieByData(CKT_SERVERLIST, pItem->pItems[i]->cookie);
- }
- // allocate cookie id
- dwGroupCookie = AllocateCookie(CKT_SERVERLIST, wItemAction, 0, pGroupCookie);
- // prepare packet data
- serverPacketInit(&groupPacket, totalSize + 0x0A); // FLAP size added inside
- packFNACHeader(&groupPacket, ICQ_LISTS_FAMILY, wItemAction, 0, dwGroupCookie);
- for (i = 0; i < pItem->nItems; i++)
- packBuffer(&groupPacket, pItem->pItems[i]->packet.pData + 0x10, pItem->pItems[i]->packet.wLen - 0x10);
-
- if (bItemDouble) { // prepare second packet
- wItemAction = ((servlistgroupitemdouble*)(pItem->pItems[0]))->wAction2;
- totalSize = 0;
- // determine the total size of the packet
- for (i = 0; i < pItem->nItems; i++)
- totalSize += ((servlistgroupitemdouble*)(pItem->pItems[i]))->packet2.wLen - 0x10;
-
- pGroupCookie = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- pGroupCookie->dwAction = SSA_ACTION_GROUP;
- pGroupCookie->dwGroupCount = pItem->nItems;
- pGroupCookie->pGroupItems = (cookie_servlist_action**)SAFE_MALLOC(pItem->nItems * sizeof(cookie_servlist_action*));
- for (i = 0; i < pItem->nItems; i++)
- pGroupCookie->pGroupItems[i] = pItem->pItems[i]->cookie;
- // allocate cookie id
- dwGroupCookie = AllocateCookie(CKT_SERVERLIST, wItemAction, 0, pGroupCookie);
- // prepare packet data
- serverPacketInit(&groupPacket2, totalSize + 0x0A); // FLAP size added inside
- packFNACHeader(&groupPacket2, ICQ_LISTS_FAMILY, wItemAction, 0, dwGroupCookie);
- for (i = 0; i < pItem->nItems; i++)
- packBuffer(&groupPacket2, ((servlistgroupitemdouble*)(pItem->pItems[i]))->packet2.pData + 0x10, ((servlistgroupitemdouble*)(pItem->pItems[i]))->packet2.wLen - 0x10);
- }
- }
- else { // just send the one packet, do not create action group
- pGroupCookie = pItem->pItems[0]->cookie;
- memcpy(&groupPacket, &pItem->pItems[0]->packet, sizeof(icq_packet));
- if (bItemDouble)
- memcpy(&groupPacket2, &((servlistgroupitemdouble*)(pItem->pItems[0]))->packet2, sizeof(icq_packet));
- }
-
- // remove grouped item from queue & release grouped item
- servlistQueueCount--;
- servlistQueueList[0] = servlistQueueList[servlistQueueCount];
-
- for (i = 0; i < pItem->nItems; i++) { // release memory
- if (pItem->nItems > 1) { // free the packet only if we created the group packet
- SAFE_FREE((void**)&pItem->pItems[i]->packet.pData);
- if (pItem->pItems[i]->dwOperation & SSOG_DOUBLE)
- SAFE_FREE((void**)&((servlistgroupitemdouble*)(pItem->pItems[i]))->packet2.pData);
- }
- SAFE_FREE((void**)&pItem->pItems[i]);
- }
- SAFE_FREE((void**)&pItem);
- // resize the queue
- if (servlistQueueSize > servlistQueueCount + 6) {
- servlistQueueSize -= 4;
- servlistQueueList = (ssiqueueditems**)SAFE_REALLOC(servlistQueueList, servlistQueueSize * sizeof(ssiqueueditems*));
- }
- }
- l.unlock();
- // send group packet
- sendServPacket(&groupPacket);
- // send second group packet (if present)
- if (bItemDouble)
- sendServPacket(&groupPacket2);
- // process end operation marks
- if (nEndOperations)
- servlistEndOperation(nEndOperations);
- // loose the loop a bit
- SleepEx(100, TRUE);
- l.lock();
- }
-
- // clean-up thread
- CloseHandle(servlistQueueThreadHandle);
- servlistQueueThreadHandle = nullptr;
-
- debugLogA("Server-List: Update Board ending.");
-}
-
-void CIcqProto::servlistQueueAddGroupItem(servlistgroupitem* pGroupItem, int dwTimeout)
-{
- mir_cslock l(servlistQueueMutex);
-
- // add the packet to queue
- DWORD dwMark = pGroupItem->dwOperation & SSOF_GROUPINGMASK;
- ssiqueueditems* pItem = nullptr;
-
- // try to find compatible item
- for (int i = 0; i < servlistQueueCount; i++) {
- if ((servlistQueueList[i]->pItems[0]->dwOperation & SSOF_GROUPINGMASK) == dwMark && servlistQueueList[i]->nItems < MAX_SERVLIST_PACKET_ITEMS) { // found compatible item, check if it does not contain operation for the same server-list item
- pItem = servlistQueueList[i];
-
- for (int j = 0; j < pItem->nItems; j++)
- if (pItem->pItems[j]->cookie->wContactId == pGroupItem->cookie->wContactId && pItem->pItems[j]->cookie->wGroupId == pGroupItem->cookie->wGroupId) {
- pItem = nullptr;
- break;
- }
-
- // cannot send two operations for the same server-list record in one packet, look for another
- if (!pItem)
- continue;
-
- debugLogA("Server-List: Adding packet to item #%d with operation %x.", i, servlistQueueList[i]->pItems[0]->dwOperation);
- break;
- }
- }
- if (!pItem) { // compatible item was not found, create new one, add to queue
- pItem = (ssiqueueditems*)SAFE_MALLOC(sizeof(ssiqueueditems));
- pItem->tAdded = time(0);
- pItem->dwTimeout = dwTimeout;
-
- if (servlistQueueCount == servlistQueueSize) { // resize the queue - it is too small
- servlistQueueSize += 4;
- servlistQueueList = (ssiqueueditems**)SAFE_REALLOC(servlistQueueList, servlistQueueSize * sizeof(ssiqueueditems*));
- }
- // really add to queue
- servlistQueueList[servlistQueueCount++] = pItem;
-
- debugLogA("Server-List: Adding new item to queue.");
- }
- else if (pItem->dwTimeout > dwTimeout) {
- // if the timeout of currently added packet is shorter, update the previous one
- pItem->dwTimeout = dwTimeout;
- }
- // add GroupItem to queueditems (pItem)
- pItem->pItems[pItem->nItems++] = pGroupItem;
-
- // wake up board thread (keep sleeping or start new one)
- if (!servlistQueueThreadHandle)
- // create new board thread
- servlistQueueThreadHandle = ForkThreadEx(&CIcqProto::servlistQueueThread, &servlistQueueState, nullptr);
- else // signal thread, that queue was changed during sleep
- servlistQueueState = TRUE;
-}
-
-int CIcqProto::servlistHandlePrimitives(DWORD dwOperation)
-{
- if (dwOperation & SSO_BEGIN_OPERATION) { // operation starting, no action ready yet
- servlistBeginOperation(1, dwOperation & SSOF_IMPORT_OPERATION);
- return TRUE;
- }
- if (dwOperation & SSO_END_OPERATION) { // operation ending without action
- servlistEndOperation(1);
- return TRUE;
- }
-
- return FALSE;
-}
-
-void CIcqProto::servlistPostPacket(icq_packet* packet, DWORD dwCookie, DWORD dwOperation, DWORD dwTimeout)
-{
- cookie_servlist_action* pCookie;
-
- if (servlistHandlePrimitives(dwOperation))
- return;
-
- if (!FindCookie(dwCookie, nullptr, (void**)&pCookie))
- return; // invalid cookie
-
- if (dwOperation & SSOF_SEND_DIRECTLY) { // send directly - this is for some special cases
- // begin operation if requested
- if (dwOperation & SSOF_BEGIN_OPERATION)
- servlistBeginOperation(1, dwOperation & SSOF_IMPORT_OPERATION);
-
- // send the packet
- sendServPacket(packet);
-
- // end operation if requested
- if (dwOperation & SSOF_END_OPERATION)
- servlistEndOperation(1);
- }
- else { // add to server-list update board
- // prepare group item
- servlistgroupitem *pGroupItem = (servlistgroupitem*)SAFE_MALLOC(sizeof(servlistgroupitem));
- pGroupItem->dwOperation = dwOperation;
- pGroupItem->cookie = pCookie;
- // packet data are alloced, keep them until they are sent
- memcpy(&pGroupItem->packet, packet, sizeof(icq_packet));
-
- servlistQueueAddGroupItem(pGroupItem, dwTimeout);
- }
-}
-
-void CIcqProto::servlistPostPacketDouble(icq_packet* packet1, DWORD dwCookie, DWORD dwOperation, DWORD dwTimeout, icq_packet* packet2, WORD wAction2)
-{
- cookie_servlist_action* pCookie;
-
- if (servlistHandlePrimitives(dwOperation))
- return;
-
- if (!FindCookie(dwCookie, nullptr, (void**)&pCookie))
- return; // invalid cookie
-
- if (dwOperation & SSOF_SEND_DIRECTLY) { // send directly - this is for some special cases
- // begin operation if requested
- if (dwOperation & SSOF_BEGIN_OPERATION)
- servlistBeginOperation(1, dwOperation & SSOF_IMPORT_OPERATION);
-
- // send the packets
- sendServPacket(packet1);
- sendServPacket(packet2);
-
- // end operation if requested
- if (dwOperation & SSOF_END_OPERATION)
- servlistEndOperation(1);
- }
- else { // add to server-list update board
- servlistgroupitemdouble* pGroupItem;
-
- // prepare group item
- pGroupItem = (servlistgroupitemdouble*)SAFE_MALLOC(sizeof(servlistgroupitemdouble));
- pGroupItem->dwOperation = dwOperation;
- pGroupItem->cookie = pCookie;
- pGroupItem->wAction2 = wAction2;
- // packets data are alloced, keep them until they are sent
- memcpy(&pGroupItem->packet, packet1, sizeof(icq_packet));
- memcpy(&pGroupItem->packet2, packet2, sizeof(icq_packet));
-
- servlistQueueAddGroupItem((servlistgroupitem*)pGroupItem, dwTimeout);
- }
-}
-
-void CIcqProto::servlistProcessLogin()
-{
- // reset edit state counter
- servlistEditCount = 0;
-
- /// TODO: preserve queue state in DB! restore here!
-
- // if the server-list queue contains items and thread is not running, start it
- if (servlistQueueCount && !servlistQueueThreadHandle)
- servlistQueueThreadHandle = ForkThreadEx(&CIcqProto::servlistQueueThread, &servlistQueueState, nullptr);
-}
-
-// HERE ENDS SERVER-LIST UPDATE BOARD IMPLEMENTATION //
-///////////////////////////////////////////////////////
-//===================================================//
-
-// PENDING SERVER-LIST OPERATIONS
-//
-#define ITEM_PENDING_CONTACT 0x01
-#define ITEM_PENDING_GROUP 0x02
-
-#define CALLBACK_RESULT_CONTINUE 0x00
-#define CALLBACK_RESULT_POSTPONE 0x0D
-#define CALLBACK_RESULT_PURGE 0x10
-
-
-#define SPOF_AUTO_CREATE_ITEM 0x01
-
-int CIcqProto::servlistPendingFindItem(int nType, MCONTACT hContact, const char *pszGroup)
-{
- if (servlistPendingList)
- for (int i = 0; i < servlistPendingCount; i++)
- if (servlistPendingList[i]->nType == nType)
- if (((nType == ITEM_PENDING_CONTACT) && (servlistPendingList[i]->hContact == hContact)) ||
- ((nType == ITEM_PENDING_GROUP) && (!mir_strcmp(servlistPendingList[i]->szGroup, pszGroup))))
- return i;
-
- return -1;
-}
-
-void CIcqProto::servlistPendingAddItem(servlistpendingitem *pItem)
-{
- if (servlistPendingCount >= servlistPendingSize) { // add new
- servlistPendingSize += 10;
- servlistPendingList = (servlistpendingitem**)SAFE_REALLOC(servlistPendingList, servlistPendingSize * sizeof(servlistpendingitem*));
- }
-
- servlistPendingList[servlistPendingCount++] = pItem;
-}
-
-servlistpendingitem* CIcqProto::servlistPendingRemoveItem(int nType, MCONTACT hContact, const char *pszGroup)
-{
- // unregister pending item, trigger pending operations
- int iItem;
- servlistpendingitem *pItem = nullptr;
-
- mir_cslock l(servlistMutex);
-
- if ((iItem = servlistPendingFindItem(nType, hContact, pszGroup)) != -1) { // found, remove from the pending list
- pItem = servlistPendingList[iItem];
-
- servlistPendingList[iItem] = servlistPendingList[--servlistPendingCount];
-
- if (servlistPendingCount + 10 < servlistPendingSize) {
- servlistPendingSize -= 5;
- servlistPendingList = (servlistpendingitem**)SAFE_REALLOC(servlistPendingList, servlistPendingSize * sizeof(servlistpendingitem*));
- }
-
- // was the first operation was created automatically to postpone ItemAdd?
- if (pItem->operations && pItem->operations[0].flags & SPOF_AUTO_CREATE_ITEM) { // yes, add new item
- servlistpendingitem *pNewItem = (servlistpendingitem*)SAFE_MALLOC(sizeof(servlistpendingitem));
-
- if (pNewItem) { // move the remaining operations
- if (pItem->nType == ITEM_PENDING_CONTACT)
- debugLogA("Server-List: Resuming contact %x operation.", pItem->hContact);
- else
- debugLogA("Server-List: Resuming group \"%s\" operation.", pItem->szGroup);
-
- pNewItem->nType = pItem->nType;
- pNewItem->hContact = pItem->hContact;
- pNewItem->szGroup = null_strdup(pItem->szGroup);
- pNewItem->wContactID = pItem->wContactID;
- pNewItem->wGroupID = pItem->wGroupID;
- pNewItem->operationsCount = pItem->operationsCount - 1;
- pNewItem->operations = (servlistpendingoperation*)SAFE_MALLOC(pNewItem->operationsCount * sizeof(servlistpendingoperation));
- memcpy(pNewItem->operations, pItem->operations + 1, pNewItem->operationsCount * sizeof(servlistpendingoperation));
- pItem->operationsCount = 1;
-
- servlistPendingAddItem(pNewItem);
- // clear the flag
- pItem->operations[0].flags &= ~SPOF_AUTO_CREATE_ITEM;
- }
- }
- }
- else debugLogA("Server-List Error: Trying to remove non-existing pending %s.", nType == ITEM_PENDING_CONTACT ? "contact" : "group");
-
- return pItem;
-}
-
-
-void CIcqProto::servlistPendingAddContactOperation(MCONTACT hContact, LPARAM param, PENDING_CONTACT_CALLBACK callback, DWORD flags)
-{
- // add postponed operation (add contact, update contact, regroup resume, etc.)
- // - after contact is added
- int iItem;
- servlistpendingitem *pItem = nullptr;
-
- mir_cslock l(servlistMutex);
-
- if ((iItem = servlistPendingFindItem(ITEM_PENDING_CONTACT, hContact, nullptr)) != -1)
- pItem = servlistPendingList[iItem];
-
- if (pItem) {
- int iOperation = pItem->operationsCount++;
-
- pItem->operations = (servlistpendingoperation*)SAFE_REALLOC(pItem->operations, pItem->operationsCount * sizeof(servlistpendingoperation));
- pItem->operations[iOperation].param = param;
- pItem->operations[iOperation].callback = (PENDING_GROUP_CALLBACK)callback;
- pItem->operations[iOperation].flags = flags;
- }
- else debugLogA("Server-List Error: Trying to add pending operation to a non existing contact.");
-}
-
-void CIcqProto::servlistPendingAddGroupOperation(const char *pszGroup, LPARAM param, PENDING_GROUP_CALLBACK callback, DWORD flags)
-{
- // add postponed operation - after group is added
- int iItem;
- servlistpendingitem *pItem = nullptr;
-
- mir_cslock l(servlistMutex);
-
- if ((iItem = servlistPendingFindItem(ITEM_PENDING_GROUP, NULL, pszGroup)) != -1)
- pItem = servlistPendingList[iItem];
-
- if (pItem) {
- int iOperation = pItem->operationsCount++;
-
- pItem->operations = (servlistpendingoperation*)SAFE_REALLOC(pItem->operations, pItem->operationsCount * sizeof(servlistpendingoperation));
- pItem->operations[iOperation].param = param;
- pItem->operations[iOperation].callback = callback;
- pItem->operations[iOperation].flags = flags;
- }
- else debugLogA("Server-List Error: Trying to add pending operation to a non existing group.");
-}
-
-int CIcqProto::servlistPendingAddContact(MCONTACT hContact, WORD wContactID, WORD wGroupID, LPARAM param, PENDING_CONTACT_CALLBACK callback, int bDoInline, LPARAM operationParam, PENDING_CONTACT_CALLBACK operationCallback)
-{
- int iItem;
- servlistpendingitem *pItem = nullptr;
-
- mir_cslockfull l(servlistMutex);
-
- if ((iItem = servlistPendingFindItem(ITEM_PENDING_CONTACT, hContact, nullptr)) != -1)
- pItem = servlistPendingList[iItem];
-
- if (pItem) {
- debugLogA("Server-List: Pending contact %x already in list; adding as operation.", hContact);
-
- servlistPendingAddContactOperation(hContact, param, callback, SPOF_AUTO_CREATE_ITEM);
-
- if (operationCallback)
- servlistPendingAddContactOperation(hContact, operationParam, operationCallback, 0);
- return 0; // Pending
- }
-
- debugLogA("Server-List: Starting contact %x operation.", hContact);
-
- pItem = (servlistpendingitem *)SAFE_MALLOC(sizeof(servlistpendingitem));
- pItem->nType = ITEM_PENDING_CONTACT;
- pItem->hContact = hContact;
- pItem->wContactID = wContactID;
- pItem->wGroupID = wGroupID;
-
- servlistPendingAddItem(pItem);
-
- if (operationCallback)
- servlistPendingAddContactOperation(hContact, operationParam, operationCallback, 0);
-
- l.unlock();
-
- if (bDoInline) // not postponed, called directly if requested
- (this->*callback)(hContact, wContactID, wGroupID, param, PENDING_RESULT_INLINE);
-
- return 1; // Ready
-}
-
-int CIcqProto::servlistPendingAddGroup(const char *pszGroup, WORD wGroupID, LPARAM param, PENDING_GROUP_CALLBACK callback, int bDoInline, LPARAM operationParam, PENDING_GROUP_CALLBACK operationCallback)
-{
- int iItem;
- servlistpendingitem *pItem = nullptr;
-
- mir_cslockfull l(servlistMutex);
-
- if ((iItem = servlistPendingFindItem(ITEM_PENDING_GROUP, NULL, pszGroup)) != -1)
- pItem = servlistPendingList[iItem];
-
- if (pItem) {
- debugLogA("Server-List: Pending group \"%s\" already in list; adding as operation.", pszGroup);
-
- servlistPendingAddGroupOperation(pszGroup, param, callback, SPOF_AUTO_CREATE_ITEM);
-
- if (operationCallback)
- servlistPendingAddGroupOperation(pszGroup, operationParam, operationCallback, 0);
- return 0; // Pending
- }
-
- debugLogA("Server-List: Starting group \"%s\" operation.", pszGroup);
-
- pItem = (servlistpendingitem *)SAFE_MALLOC(sizeof(servlistpendingitem));
- pItem->nType = ITEM_PENDING_GROUP;
- pItem->szGroup = null_strdup(pszGroup);
- pItem->wGroupID = wGroupID;
-
- servlistPendingAddItem(pItem);
-
- if (operationCallback)
- servlistPendingAddGroupOperation(pszGroup, operationParam, operationCallback, 0);
-
- l.unlock();
-
- if (bDoInline) // not postponed, called directly if requested
- (this->*callback)(pszGroup, wGroupID, param, PENDING_RESULT_INLINE);
-
- return 1; // Ready
-}
-
-void CIcqProto::servlistPendingRemoveContact(MCONTACT hContact, WORD wContactID, WORD wGroupID, int nResult)
-{
- debugLogA("Server-List: %s contact %x operation.", (nResult != PENDING_RESULT_PURGE) ? "Ending" : "Purging", hContact);
-
- servlistpendingitem *pItem = servlistPendingRemoveItem(ITEM_PENDING_CONTACT, hContact, nullptr);
-
- if (pItem) { // process pending operations
- if (pItem->operations) {
- for (int i = 0; i < pItem->operationsCount; i++) {
- int nCallbackState = (this->*(PENDING_CONTACT_CALLBACK)(pItem->operations[i].callback))(hContact, wContactID, wGroupID, pItem->operations[i].param, nResult);
-
- if (nResult != PENDING_RESULT_PURGE && nCallbackState == CALLBACK_RESULT_POSTPONE) { // any following pending operations cannot be processed now, move them to the new pending contact
- for (int j = i + 1; j < pItem->operationsCount; j++)
- servlistPendingAddContactOperation(hContact, pItem->operations[j].param, (PENDING_CONTACT_CALLBACK)(pItem->operations[j].callback), pItem->operations[j].flags);
- break;
- }
- else if (nCallbackState == CALLBACK_RESULT_PURGE) // purge all following operations - fatal failure occured
- nResult = PENDING_RESULT_PURGE;
- }
- SAFE_FREE((void**)&pItem->operations);
- }
- // release item's memory
- SAFE_FREE((void**)&pItem);
- }
- else debugLogA("Server-List Error: Trying to remove a non existing pending contact.");
-}
-
-void CIcqProto::servlistPendingRemoveGroup(const char *pszGroup, WORD wGroupID, int nResult)
-{
- debugLogA("Server-List: %s group \"%s\" operation.", (nResult != PENDING_RESULT_PURGE) ? "Ending" : "Purging", pszGroup);
-
- servlistpendingitem *pItem = servlistPendingRemoveItem(ITEM_PENDING_GROUP, NULL, pszGroup);
-
- if (pItem) { // process pending operations
- if (pItem->operations) {
- for (int i = 0; i < pItem->operationsCount; i++) {
- int nCallbackState = (this->*pItem->operations[i].callback)(pItem->szGroup, wGroupID, pItem->operations[i].param, nResult);
-
- if (nResult != PENDING_RESULT_PURGE && nCallbackState == CALLBACK_RESULT_POSTPONE) { // any following pending operations cannot be processed now, move them to the new pending group
- for (int j = i + 1; j < pItem->operationsCount; j++)
- servlistPendingAddGroupOperation(pItem->szGroup, pItem->operations[j].param, pItem->operations[j].callback, pItem->operations[j].flags);
- break;
- }
- else if (nCallbackState == CALLBACK_RESULT_PURGE) { // purge all following operations - fatal failure occured
- nResult = PENDING_RESULT_PURGE;
- }
- }
- SAFE_FREE((void**)&pItem->operations);
- }
- // release item's memory
- SAFE_FREE((void**)&pItem->szGroup);
- SAFE_FREE((void**)&pItem);
- }
- else debugLogA("Server-List Error: Trying to remove a non existing pending group.");
-}
-
-// Remove All pending operations
-void CIcqProto::servlistPendingFlushOperations()
-{
- mir_cslock l(servlistMutex);
-
- for (int i = servlistPendingCount; i; i--) { // purge all items
- servlistpendingitem *pItem = servlistPendingList[i - 1];
-
- if (pItem->nType == ITEM_PENDING_CONTACT)
- servlistPendingRemoveContact(pItem->hContact, 0, 0, PENDING_RESULT_PURGE);
- else if (pItem->nType == ITEM_PENDING_GROUP)
- servlistPendingRemoveGroup(pItem->szGroup, 0, PENDING_RESULT_PURGE);
- }
- // release the list completely
- SAFE_FREE((void**)&servlistPendingList);
- servlistPendingCount = 0;
- servlistPendingSize = 0;
-}
-
-// END OF SERVER-LIST PENDING OPERATIONS
-////
-
-// used for adding new contacts to list - sync with visible items
-void CIcqProto::AddJustAddedContact(MCONTACT hContact)
-{
- mir_cslock l(servlistMutex);
-
- if (nJustAddedCount >= nJustAddedSize) {
- nJustAddedSize += 10;
- pdwJustAddedList = (MCONTACT*)SAFE_REALLOC(pdwJustAddedList, nJustAddedSize * sizeof(MCONTACT));
- }
-
- pdwJustAddedList[nJustAddedCount] = hContact;
- nJustAddedCount++;
-}
-
-// was the contact added during this serv-list load
-BOOL CIcqProto::IsContactJustAdded(MCONTACT hContact)
-{
- mir_cslock l(servlistMutex);
-
- if (pdwJustAddedList)
- for (int i = 0; i < nJustAddedCount; i++)
- if (pdwJustAddedList[i] == hContact)
- return TRUE;
-
- return FALSE;
-}
-
-
-void CIcqProto::FlushJustAddedContacts()
-{
- mir_cslock l(servlistMutex);
-
- SAFE_FREE((void**)&pdwJustAddedList);
- nJustAddedSize = 0;
- nJustAddedCount = 0;
-}
-
-// Add a server ID to the list of reserved IDs.
-// To speed up the process, no checks is done, if
-// you try to reserve an ID twice, it will be added again.
-// You should call CheckServerID before reserving an ID.
-void CIcqProto::ReserveServerID(WORD wID, int bGroupType, int bFlags)
-{
- { mir_cslock l(servlistMutex);
- if (nServerIDListCount >= nServerIDListSize) {
- nServerIDListSize += 100;
- pdwServerIDList = (DWORD*)SAFE_REALLOC(pdwServerIDList, nServerIDListSize * sizeof(DWORD));
- }
-
- pdwServerIDList[nServerIDListCount] = wID | (bGroupType & 0x00FF0000) | (bFlags & 0xFF000000);
- nServerIDListCount++;
- }
-
- if (!bIsSyncingCL)
- StoreServerIDs();
-}
-
-// Remove a server ID from the list of reserved IDs.
-// Used for deleting contacts and other modifications.
-void CIcqProto::FreeServerID(WORD wID, int bGroupType)
-{
- DWORD dwId = wID | (bGroupType & 0x00FF0000);
-
- mir_cslock l(servlistMutex);
-
- if (pdwServerIDList) {
- for (int i = 0; i < nServerIDListCount; i++) {
- if ((pdwServerIDList[i] & 0x00FFFFFF) == dwId) { // we found it, so remove
- for (int j = i + 1; j < nServerIDListCount; j++)
- pdwServerIDList[j - 1] = pdwServerIDList[j];
-
- nServerIDListCount--;
- }
- }
- }
-}
-
-// Returns true if dwID is reserved
-BOOL CIcqProto::CheckServerID(WORD wID, unsigned int wCount)
-{
- mir_cslock l(servlistMutex);
-
- if (pdwServerIDList) {
- for (int i = 0; i < nServerIDListCount; i++) {
- if (((pdwServerIDList[i] & 0xFFFF) >= wID) && ((pdwServerIDList[i] & 0xFFFF) <= wID + wCount))
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-void CIcqProto::FlushServerIDs()
-{
- mir_cslock l(servlistMutex);
-
- SAFE_FREE((void**)&pdwServerIDList);
- nServerIDListCount = 0;
- nServerIDListSize = 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-struct GroupReserveIdsEnumParam
-{
- CIcqProto *ppro;
- char *szModule;
-};
-
-static int GroupReserveIdsEnumProc(const char *szSetting, void *lParam)
-{
- if (szSetting && mir_strlen(szSetting) < 5) {
- // it is probably server group
- GroupReserveIdsEnumParam *param = (GroupReserveIdsEnumParam*)lParam;
- char val[MAX_PATH + 2]; // dummy
- if (db_get_static(0, param->szModule, szSetting, val, MAX_PATH))
- if (db_get_static_utf(0, param->szModule, szSetting, val, MAX_PATH))
- return 0; // we failed also, invalid setting
-
- param->ppro->ReserveServerID((WORD)strtoul(szSetting, nullptr, 0x10), SSIT_GROUP, 0);
- param->ppro->debugLogA("Loaded group %u:'%s'", strtoul(szSetting, nullptr, 0x10), val);
- }
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Load all known server IDs from DB to list
-
-void CIcqProto::LoadServerIDs()
-{
- WORD wSrvID;
- int nGroups = 0, nContacts = 0, nPermits = 0, nDenys = 0, nIgnores = 0, nUnhandled = 0;
-
- mir_cslockfull l(servlistMutex);
- if (wSrvID = getWord(DBSETTING_SERVLIST_AVATAR, 0))
- ReserveServerID(wSrvID, SSIT_ITEM, 0);
- if (wSrvID = getWord(DBSETTING_SERVLIST_PHOTO, 0))
- ReserveServerID(wSrvID, SSIT_ITEM, 0);
- if (wSrvID = getWord(DBSETTING_SERVLIST_PRIVACY, 0))
- ReserveServerID(wSrvID, SSIT_ITEM, 0);
- if (wSrvID = getWord(DBSETTING_SERVLIST_METAINFO, 0))
- ReserveServerID(wSrvID, SSIT_ITEM, 0);
- if (wSrvID = getWord("SrvImportID", 0))
- ReserveServerID(wSrvID, SSIT_ITEM, 0);
-
- int nStart = nServerIDListCount;
-
- char szModule[MAX_PATH];
- mir_snprintf(szModule, "%sSrvGroups", m_szModuleName);
- GroupReserveIdsEnumParam param = { this, szModule };
-
- db_enum_settings(NULL, &GroupReserveIdsEnumProc, szModule, &param);
-
- nGroups = nServerIDListCount - nStart;
-
- for (auto &hContact : AccContacts()) {
- if (wSrvID = getWord(hContact, DBSETTING_SERVLIST_ID, 0)) {
- ReserveServerID(wSrvID, SSIT_ITEM, 0);
- nContacts++;
- }
- if (wSrvID = getWord(hContact, DBSETTING_SERVLIST_DENY, 0)) {
- ReserveServerID(wSrvID, SSIT_ITEM, 0);
- nDenys++;
- }
- if (wSrvID = getWord(hContact, DBSETTING_SERVLIST_PERMIT, 0)) {
- ReserveServerID(wSrvID, SSIT_ITEM, 0);
- nPermits++;
- }
- if (wSrvID = getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0)) {
- ReserveServerID(wSrvID, SSIT_ITEM, 0);
- nIgnores++;
- }
- }
- l.unlock();
-
- DBVARIANT dbv = { 0 };
- if (!getSetting(NULL, DBSETTING_SERVLIST_UNHANDLED, &dbv)) {
- int dataLen = dbv.cpbVal;
- BYTE *pData = dbv.pbVal;
-
- while (dataLen >= 4) {
- BYTE bGroupType;
- BYTE bFlags;
-
- unpackLEWord(&pData, &wSrvID);
- unpackByte(&pData, &bGroupType);
- unpackByte(&pData, &bFlags);
-
- ReserveServerID(wSrvID, bGroupType, bFlags);
- dataLen -= 4;
- nUnhandled++;
- }
-
- db_free(&dbv);
- }
-
- debugLogA("Loaded SSI: %d contacts, %d groups, %d permit, %d deny, %d ignore, %d unknown items.", nContacts, nGroups, nPermits, nDenys, nIgnores, nUnhandled);
-}
-
-void CIcqProto::StoreServerIDs() /// TODO: allow delayed
-{
- BYTE *pUnhandled = nullptr;
- size_t cbUnhandled = 0;
-
- mir_cslockfull l(servlistMutex);
- if (pdwServerIDList)
- for (int i = 0; i < nServerIDListCount; i++)
- if ((pdwServerIDList[i] & 0xFF000000) == SSIF_UNHANDLED) {
- ppackLEWord(&pUnhandled, &cbUnhandled, pdwServerIDList[i] & 0xFFFF);
- ppackByte(&pUnhandled, &cbUnhandled, (pdwServerIDList[i] & 0x00FF0000) >> 0x10);
- ppackByte(&pUnhandled, &cbUnhandled, (pdwServerIDList[i] & 0xFF000000) >> 0x18);
- }
-
- l.unlock();
-
- if (pUnhandled)
- setSettingBlob(NULL, DBSETTING_SERVLIST_UNHANDLED, pUnhandled, (int)cbUnhandled);
- else
- delSetting(DBSETTING_SERVLIST_UNHANDLED);
-
- SAFE_FREE((void**)&pUnhandled);
-}
-
-// Generate server ID with wCount IDs free after it, for sub-groups.
-WORD CIcqProto::GenerateServerID(int bGroupType, int bFlags, int wCount)
-{
- WORD wId;
-
- while (TRUE) {
- // Randomize a new ID
- // Max value is probably 0x7FFF, lowest value is probably 0x0001 (generated by Icq2Go)
- // We use range 0x1000-0x7FFF.
- wId = (WORD)RandRange(0x1000, 0x7FFF);
-
- if (!CheckServerID(wId, wCount))
- break;
- }
-
- ReserveServerID(wId, bGroupType, bFlags);
- return wId;
-}
-
-/***********************************************
-*
-* --- Low-level packet sending functions ---
-*
-*/
-
-struct doubleServerItemObject
-{
- WORD wAction;
- icq_packet packet;
-};
-
-DWORD CIcqProto::icq_sendServerItem(DWORD dwCookie, WORD wAction, WORD wGroupId, WORD wItemId, const char *szName, BYTE *pTLVs, size_t nTlvLength, WORD wItemType, DWORD dwOperation, DWORD dwTimeout, void **doubleObject)
-{
- // Prepare item name length
- size_t nNameLen = mir_strlen(szName);
-
- // Build the packet
- icq_packet packet;
- serverPacketInit(&packet, nNameLen + 20 + nTlvLength);
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, wAction, 0, dwCookie);
- packWord(&packet, WORD(nNameLen));
- if (nNameLen)
- packBuffer(&packet, (LPBYTE)szName, nNameLen);
- packWord(&packet, wGroupId);
- packWord(&packet, wItemId);
- packWord(&packet, wItemType);
- packWord(&packet, WORD(nTlvLength));
- if (nTlvLength)
- packBuffer(&packet, pTLVs, nTlvLength);
-
- if (!doubleObject) // Send the packet and return the cookie
- servlistPostPacket(&packet, dwCookie, dwOperation | wAction, dwTimeout);
- else {
- if (*doubleObject) { // Send both packets and return the cookie
- doubleServerItemObject* helper = (doubleServerItemObject*)*doubleObject;
-
- servlistPostPacketDouble(&helper->packet, dwCookie, dwOperation | helper->wAction, dwTimeout, &packet, wAction);
- SAFE_FREE(doubleObject);
- }
- else { // Create helper object, return the cookie
- doubleServerItemObject* helper = (doubleServerItemObject*)SAFE_MALLOC(sizeof(doubleServerItemObject));
-
- if (helper) {
- helper->wAction = wAction;
- memcpy(&helper->packet, &packet, sizeof(icq_packet));
- *doubleObject = helper;
- }
- else // memory alloc failed
- return 0;
- }
- }
-
- // Force reload of server-list after change
- setWord("SrvRecordCount", 0);
-
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_sendServerContact(MCONTACT hContact, DWORD dwCookie, WORD wAction, WORD wGroupId, WORD wContactId, DWORD dwOperation, DWORD dwTimeout, void **doubleObject)
-{
- BYTE *pData = nullptr, *pMetaToken = nullptr, *pMetaTime = nullptr;
- int nDataLen = 0, nMetaTokenLen = 0, nMetaTimeLen = 0;
-
- // Prepare UID
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid)) {
- debugLogA("Buddy upload failed (UID missing).");
- return 0;
- }
-
- BYTE bAuth = getByte(hContact, "Auth", 0);
- char *szNick = getSettingStringUtf(hContact, "CList", "MyHandle", nullptr);
- char *szNote = getSettingStringUtf(hContact, "UserInfo", "MyNotes", nullptr);
-
- DBVARIANT dbv;
- if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &dbv)) {
- nMetaTokenLen = dbv.cpbVal;
- pMetaToken = (BYTE*)_alloca(dbv.cpbVal);
- memcpy(pMetaToken, dbv.pbVal, dbv.cpbVal);
-
- db_free(&dbv);
- }
- if (!getSetting(hContact, DBSETTING_METAINFO_TIME, &dbv)) {
- nMetaTimeLen = dbv.cpbVal;
- pMetaTime = (BYTE*)_alloca(dbv.cpbVal);
- for (int i = 0; i < dbv.cpbVal; i++)
- pMetaTime[i] = dbv.pbVal[dbv.cpbVal - i - 1];
-
- db_free(&dbv);
- }
-
- if (!getSetting(hContact, DBSETTING_SERVLIST_DATA, &dbv)) { // read additional server item data
- nDataLen = dbv.cpbVal;
- pData = (BYTE*)_alloca(nDataLen);
- memcpy(pData, dbv.pbVal, nDataLen);
-
- db_free(&dbv);
- }
-
- size_t nNickLen = mir_strlen(szNick);
- size_t nNoteLen = mir_strlen(szNote);
-
- // Limit the strings
- int bDataTooLong = FALSE;
- if (nNickLen > MAX_SSI_TLV_NAME_SIZE) {
- bDataTooLong = TRUE;
- nNickLen = null_strcut(szNick, MAX_SSI_TLV_NAME_SIZE);
- }
- if (nNoteLen > MAX_SSI_TLV_COMMENT_SIZE) {
- bDataTooLong = TRUE;
- nNoteLen = null_strcut(szNote, MAX_SSI_TLV_COMMENT_SIZE);
- }
- if (bDataTooLong) { // Inform the user
- /// TODO: do something with this for Manage Server-List dialog.
- if (wAction != ICQ_LISTS_REMOVEFROMLIST) // do not report this when removing from list
- icq_LogMessage(LOG_WARNING, LPGEN("The contact's information was too big and was truncated."));
- }
-
- // Build the packet
- size_t wTLVlen = (nNickLen ? 4 + nNickLen : 0) + (nNoteLen ? 4 + nNoteLen : 0) + (bAuth ? 4 : 0) + nDataLen + (nMetaTokenLen ? 4 + nMetaTokenLen : 0) + (nMetaTimeLen ? 4 + nMetaTimeLen : 0);
-
- // Initialize our handy data buffer
- icq_packet pBuffer;
- pBuffer.wPlace = 0;
- pBuffer.pData = (BYTE *)_alloca(wTLVlen);
- pBuffer.wLen = (WORD)wTLVlen;
-
- if (nNickLen)
- packTLV(&pBuffer, SSI_TLV_NAME, nNickLen, (LPBYTE)szNick); // Nickname TLV
-
- if (nNoteLen)
- packTLV(&pBuffer, SSI_TLV_COMMENT, nNoteLen, (LPBYTE)szNote); // Comment TLV
-
- if (nMetaTokenLen)
- packTLV(&pBuffer, SSI_TLV_METAINFO_TOKEN, nMetaTokenLen, pMetaToken);
-
- if (nMetaTimeLen)
- packTLV(&pBuffer, SSI_TLV_METAINFO_TIME, nMetaTimeLen, pMetaTime);
-
- if (pData)
- packBuffer(&pBuffer, pData, nDataLen);
-
- if (bAuth) // icq5 gives this as last TLV
- packDWord(&pBuffer, 0x00660000); // "Still waiting for auth" TLV
-
- SAFE_FREE((void**)&szNick);
- SAFE_FREE((void**)&szNote);
-
- return icq_sendServerItem(dwCookie, wAction, wGroupId, wContactId, strUID(dwUin, szUid), pBuffer.pData, wTLVlen, SSI_ITEM_BUDDY, dwOperation, dwTimeout, doubleObject);
-}
-
-DWORD CIcqProto::icq_sendSimpleItem(DWORD dwCookie, WORD wAction, DWORD dwUin, char* szUID, WORD wGroupId, WORD wItemId, WORD wItemType, DWORD dwOperation, DWORD dwTimeout)
-{ // for privacy items
- return icq_sendServerItem(dwCookie, wAction, wGroupId, wItemId, strUID(dwUin, szUID), nullptr, 0, wItemType, dwOperation, dwTimeout, nullptr);
-}
-
-DWORD CIcqProto::icq_sendServerGroup(DWORD dwCookie, WORD wAction, WORD wGroupId, const char *szName, void *pContent, int cbContent, DWORD dwOperationFlags)
-{
- WORD wTLVlen;
- icq_packet pBuffer; // I reuse the ICQ packet type as a generic buffer
- // I should be ashamed! ;)
-
- if (mir_strlen(szName) == 0 && wGroupId != 0) {
- debugLogA("Group upload failed (GroupName missing).");
- return 0; // without name we could not change the group
- }
-
- // Calculate buffer size
- wTLVlen = (cbContent ? 4 + cbContent : 0);
-
- // Initialize our handy data buffer
- pBuffer.wPlace = 0;
- pBuffer.pData = (BYTE *)_alloca(wTLVlen);
- pBuffer.wLen = wTLVlen;
-
- if (wTLVlen)
- packTLV(&pBuffer, SSI_TLV_SUBITEMS, cbContent, (LPBYTE)pContent); // Groups TLV
-
- return icq_sendServerItem(dwCookie, wAction, wGroupId, 0, szName, pBuffer.pData, wTLVlen, SSI_ITEM_GROUP, SSOP_GROUP_ACTION | dwOperationFlags, 400, nullptr);
-}
-
-DWORD CIcqProto::icq_modifyServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wAction, DWORD dwOperation, WORD wItemId, WORD wType)
-{
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- DWORD dwCookie;
-
- if (ack) {
- ack->dwAction = dwOperation; // remove privacy item
- ack->hContact = hContact;
- ack->wContactId = wItemId;
-
- dwCookie = AllocateCookie(CKT_SERVERLIST, wAction, hContact, ack);
- }
- else // cookie failed
- return 0;
-
- return icq_sendSimpleItem(dwCookie, wAction, dwUin, szUid, 0, wItemId, wType, SSOP_ITEM_ACTION, 400);
-}
-
-DWORD CIcqProto::icq_removeServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wItemId, WORD wType)
-{
- return icq_modifyServerPrivacyItem(hContact, dwUin, szUid, ICQ_LISTS_REMOVEFROMLIST, SSA_PRIVACY_REMOVE, wItemId, wType);
-}
-
-DWORD CIcqProto::icq_addServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wItemId, WORD wType)
-{
- return icq_modifyServerPrivacyItem(hContact, dwUin, szUid, ICQ_LISTS_ADDTOLIST, SSA_PRIVACY_ADD, wItemId, wType);
-}
-
-/*****************************************
-* --- Contact DB Utilities ---
-*/
-
-/// TODO: do not check by plugin version, check by ServListStructures version!
-int CIcqProto::IsServerGroupsDefined()
-{
- int iRes = 1;
-
- if (getDword("Version", 0) < 0x00030608) { // group cache & linking data too old, flush, reload from server
- char szModule[MAX_PATH];
-
- // flush obsolete linking data
- mir_snprintf(szModule, "%sGroups", m_szModuleName);
- db_delete_module(0, szModule);
-
- iRes = 0; // no groups defined, or older version
- }
- // store our current version
- setDword("Version", ICQ_PLUG_VERSION & 0x00FFFFFF);
-
- return iRes;
-}
-
-void CIcqProto::FlushSrvGroupsCache()
-{
- char szModule[MAX_PATH];
- mir_snprintf(szModule, "%sSrvGroups", m_szModuleName);
- db_delete_module(0, szModule);
-}
-
-// Look thru DB and collect all ContactIDs from a group
-void* CIcqProto::collectBuddyGroup(WORD wGroupID, int *count)
-{
- WORD* buf = nullptr;
- int cnt = 0;
- WORD wItemID;
-
- for (auto &hContact : AccContacts()) {
- if (wGroupID == getWord(hContact, DBSETTING_SERVLIST_GROUP, 0)) { // add only buddys from specified group
- wItemID = getWord(hContact, DBSETTING_SERVLIST_ID, 0);
-
- if (wItemID) { // valid ID, add
- cnt++;
- buf = (WORD*)SAFE_REALLOC(buf, cnt*sizeof(WORD));
- buf[cnt - 1] = wItemID;
- if (!count) break;
- }
- }
- }
-
- if (count)
- *count = cnt << 1; // we return size in bytes
- return buf;
-}
-
-// Look thru DB and collect all GroupIDs
-void* CIcqProto::collectGroups(int *count)
-{
- WORD *buf = nullptr;
- int cnt = 0;
- int i;
- WORD wGroupID;
-
- for (auto &hContact : AccContacts()) {
- if (wGroupID = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0)) { // add only valid IDs
- for (i = 0; i < cnt; i++) // check for already added ids
- if (buf[i] == wGroupID)
- break;
-
- // not preset, add
- if (i == cnt) {
- cnt++;
- buf = (WORD*)SAFE_REALLOC(buf, cnt*sizeof(WORD));
- buf[i] = wGroupID;
- }
- }
- }
-
- *count = cnt << 1;
- return buf;
-}
-
-static int GroupLinksEnumProc(const char *szSetting, void *lParam)
-{
- // check link target, add if match
- if (db_get_w(0, ((char**)lParam)[2], szSetting, 0) == (WORD)((char**)lParam)[1]) {
- char** block = (char**)SAFE_MALLOC(2 * sizeof(char*));
- block[1] = null_strdup(szSetting);
- block[0] = ((char**)lParam)[0];
- ((char**)lParam)[0] = (char*)block;
- }
- return 0;
-}
-
-void CIcqProto::removeGroupPathLinks(WORD wGroupID)
-{
- // remove miranda grouppath links targeting to this groupid
- char szModule[MAX_PATH];
- char* pars[3];
-
- mir_snprintf(szModule, "%sGroups", m_szModuleName);
-
- pars[0] = nullptr;
- pars[1] = (char*)wGroupID;
- pars[2] = szModule;
-
- if (!db_enum_settings(NULL, &GroupLinksEnumProc, szModule, pars)) { // we found some links, remove them
- char** list = (char**)pars[0];
- while (list) {
- void* bet;
-
- db_unset(0, szModule, list[1]);
- SAFE_FREE((void**)&list[1]);
- bet = list;
- list = (char**)list[0];
- SAFE_FREE((void**)&bet);
- }
- }
-}
-
-char* CIcqProto::getServListGroupName(WORD wGroupID)
-{
- char szModule[MAX_PATH];
- char szGroup[16];
-
- if (!wGroupID) {
- debugLogA("Warning: Cannot get group name (Group ID missing)!");
- return nullptr;
- }
-
- mir_snprintf(szModule, "%sSrvGroups", m_szModuleName);
- _itoa(wGroupID, szGroup, 0x10);
-
- if (!CheckServerID(wGroupID, 0)) { // check if valid id, if not give empty and remove
- debugLogA("Removing group %u from cache...", wGroupID);
- db_unset(0, szModule, szGroup);
- return nullptr;
- }
-
- return getSettingStringUtf(NULL, szModule, szGroup, nullptr);
-}
-
-void CIcqProto::setServListGroupName(WORD wGroupID, const char *szGroupName)
-{
- char szModule[MAX_PATH];
- char szGroup[16];
-
- if (!wGroupID) {
- debugLogA("Warning: Cannot set group name (Group ID missing)!");
- return;
- }
-
- mir_snprintf(szModule, "%sSrvGroups", m_szModuleName);
- _itoa(wGroupID, szGroup, 0x10);
-
- if (szGroupName)
- db_set_utf(NULL, szModule, szGroup, szGroupName);
- else {
- db_unset(0, szModule, szGroup);
- removeGroupPathLinks(wGroupID);
- }
-}
-
-WORD CIcqProto::getServListGroupLinkID(const char *szPath)
-{
- char szModule[MAX_PATH];
- mir_snprintf(szModule, "%sGroups", m_szModuleName);
-
- WORD wGroupId = db_get_w(0, szModule, szPath, 0);
-
- if (wGroupId && !CheckServerID(wGroupId, 0)) { // known, check if still valid, if not remove
- debugLogA("Removing group \"%s\" from cache...", szPath);
- db_unset(0, szModule, szPath);
- wGroupId = 0;
- }
-
- return wGroupId;
-}
-
-void CIcqProto::setServListGroupLinkID(const char *szPath, WORD wGroupID)
-{
- char szModule[MAX_PATH];
- mir_snprintf(szModule, "%sGroups", m_szModuleName);
-
- if (wGroupID)
- db_set_w(0, szModule, szPath, wGroupID);
- else
- db_unset(0, szModule, szPath);
-}
-
-// determine if the specified clist group path exists
-//!! this function is not thread-safe due to the use of cli->pfnGetGroupName()
-int CIcqProto::getCListGroupExists(const char *szGroup)
-{
- if (!szGroup)
- return 0;
-
- size_t size = mir_strlen(szGroup) + 2;
- wchar_t *tszGroup = (wchar_t*)_alloca(size * sizeof(wchar_t));
-
- if (make_unicode_string_static(szGroup, tszGroup, size))
- for (int i = 1; TRUE; i++) {
- wchar_t *tszGroupName = (wchar_t*)Clist_GroupGetName(i, nullptr);
- if (!tszGroupName)
- break;
-
- // we have found the group
- if (!mir_wstrcmp(tszGroup, tszGroupName))
- return i;
- }
-
- return 0;
-}
-
-
-int CIcqProto::moveContactToCListGroup(MCONTACT hContact, const char *szGroup)
-{
- MGROUP hGroup = Clist_GroupCreate(0, ptrW(mir_utf8decodeW(szGroup)));
- return Clist_ContactChangeGroup(hContact, hGroup);
-}
-
-
-// utility function which counts > on start of a server group name
-static int countGroupNameLevel(const char *szGroupName)
-{
- size_t nNameLen = mir_strlen(szGroupName);
-
- for (size_t i=0; i < nNameLen; i++)
- if (szGroupName[i] != '>')
- return (int)i;
-
- return -1;
-}
-
-static int countCListGroupLevel(const char *szClistName)
-{
- size_t nNameLen = mir_strlen(szClistName);
- int level = 0;
-
- for (size_t i = 0; i < nNameLen; i++)
- if (szClistName[i] == '\\') level++;
-
- return level;
-}
-
-int CIcqProto::getServListGroupLevel(WORD wGroupId)
-{
- char *szGroupName = getServListGroupName(wGroupId);
- int cnt = -1;
-
- if (szGroupName) { // groupid is valid count group name level
- if (m_bSsiSimpleGroups)
- cnt = countCListGroupLevel(szGroupName);
- else
- cnt = countGroupNameLevel(szGroupName);
-
- SAFE_FREE((void**)&szGroupName);
- }
-
- return cnt;
-}
-
-
-// demangle group path
-char *CIcqProto::getServListGroupCListPath(WORD wGroupId)
-{
- char *szGroup = nullptr;
-
- if (szGroup = getServListGroupName(wGroupId)) { // this groupid is valid
- if (!m_bSsiSimpleGroups)
- while (strstrnull(szGroup, "\\")) *strstrnull(szGroup, "\\") = '_'; // remove invalid char
-
- if (getServListGroupLinkID(szGroup) == wGroupId) { // this grouppath is known and is for this group, set user group
- return szGroup;
- }
- else if (m_bSsiSimpleGroups) { // with simple groups it is mapped 1:1, give real serv-list group name
- setServListGroupLinkID(szGroup, wGroupId);
- return szGroup;
- }
- else { // advanced groups, determine group level
- int nGroupLevel = getServListGroupLevel(wGroupId);
-
- if (nGroupLevel > 0) { // it is probably a sub-group locate parent group
- WORD wParentGroupId = wGroupId;
- int nParentGroupLevel;
-
- do { // we look for parent group at the correct level
- wParentGroupId--;
- nParentGroupLevel = getServListGroupLevel(wParentGroupId);
- }
- while ((nParentGroupLevel >= nGroupLevel) && (nParentGroupLevel != -1));
-
- if (nParentGroupLevel == -1) { // that was not a sub-group, it was just a group starting with >
- setServListGroupLinkID(szGroup, wGroupId);
- return szGroup;
- }
-
- // recursively determine parent group clist path
- char *szParentGroup = getServListGroupCListPath(wParentGroupId);
-
- /// FIXME: properly handle ~N suffixes
- szParentGroup = (char*)SAFE_REALLOC(szParentGroup, mir_strlen(szGroup) + mir_strlen(szParentGroup) + 2);
- mir_strcat(szParentGroup, "\\");
- mir_strcat(szParentGroup, (char*)szGroup + nGroupLevel);
-
- SAFE_FREE((void**)&szGroup);
- szGroup = szParentGroup;
-
- if (getServListGroupLinkID(szGroup) == wGroupId) // known path, give
- return szGroup;
- }
-
- setServListGroupLinkID(szGroup, wGroupId);
- return szGroup;
- }
- }
- return nullptr;
-}
-
-
-static int SrvGroupNamesEnumProc(const char *szSetting, void *lParam)
-{
- // check server-group cache item
- const char **params = (const char**)lParam;
- CIcqProto *ppro = (CIcqProto*)params[0];
- char *szGroupName = ppro->getSettingStringUtf(NULL, params[3], szSetting, nullptr);
-
- if (!mir_strcmp(szGroupName, params[2]))
- params[1] = szSetting; // do not need the real value, just arbitrary non-NULL
-
- SAFE_FREE(&szGroupName);
- return 0;
-}
-
-char* CIcqProto::getServListUniqueGroupName(const char *szGroupName, int bAlloced)
-{
- // enum ICQSrvGroups and create unique name if neccessary
- char szModule[MAX_PATH];
- char *pars[4];
- int uniqueID = 1;
- char *szGroupNameBase = (char*)szGroupName;
- char *szNewGroupName = nullptr;
-
- if (!bAlloced)
- szGroupNameBase = null_strdup(szGroupName);
- null_strcut(szGroupNameBase, m_wServerListRecordNameMaxLength);
-
- mir_snprintf(szModule, "%sSrvGroups", m_szModuleName);
-
- do {
- pars[0] = (char*)this;
- pars[1] = nullptr;
- pars[2] = szNewGroupName ? szNewGroupName : szGroupNameBase;
- pars[3] = szModule;
- db_enum_settings(NULL, &SrvGroupNamesEnumProc, szModule, pars);
-
- if (pars[1]) { // the groupname already exists, create another
- SAFE_FREE((void**)&szNewGroupName);
-
- char szUnique[10];
- _itoa(uniqueID++, szUnique, 10);
- null_strcut(szGroupNameBase, m_wServerListRecordNameMaxLength - mir_strlen(szUnique) - 1);
- szNewGroupName = (char*)SAFE_MALLOC(mir_strlen(szUnique) + mir_strlen(szGroupNameBase) + 2);
- if (szNewGroupName) {
- mir_strcpy(szNewGroupName, szGroupNameBase);
- mir_strcat(szNewGroupName, "~");
- mir_strcat(szNewGroupName, szUnique);
- }
- }
- }
- while (pars[1] && szNewGroupName);
-
- if (szNewGroupName) {
- SAFE_FREE(&szGroupNameBase);
- return szNewGroupName;
- }
- if (szGroupName != szGroupNameBase) {
- SAFE_FREE(&szGroupNameBase);
- return (char*)szGroupName;
- }
- return szGroupNameBase;
-}
-
-// this is the second part of recursive event-driven procedure
-int CIcqProto::servlistCreateGroup_gotParentGroup(const char *szGroup, WORD wGroupID, LPARAM param, int nResult)
-{
- cookie_servlist_action* clue = (cookie_servlist_action*)param;
- char *szSubGroupName = clue->szGroupName;
- char *szSubGroup;
- int wSubGroupLevel = -1;
- WORD wSubGroupID;
-
- SAFE_FREE((void**)&clue);
-
- if (nResult == PENDING_RESULT_PURGE) // only cleanup
- return CALLBACK_RESULT_CONTINUE;
-
- szSubGroup = (char*)SAFE_MALLOC(mir_strlen(szGroup) + mir_strlen(szSubGroupName) + 2);
- if (szSubGroup) {
- mir_strcpy(szSubGroup, szGroup);
- mir_strcat(szSubGroup, "\\");
- mir_strcat(szSubGroup, szSubGroupName);
- }
-
- if (nResult == PENDING_RESULT_SUCCESS) // if we got an id count level
- wSubGroupLevel = getServListGroupLevel(wGroupID);
-
- if (wSubGroupLevel == -1) { // something went wrong, give the id and go away
- servlistPendingRemoveGroup(szSubGroup, wGroupID, PENDING_RESULT_FAILED);
-
- SAFE_FREE((void**)&szSubGroupName);
- SAFE_FREE((void**)&szSubGroup);
- return CALLBACK_RESULT_CONTINUE;
- }
- wSubGroupLevel++; // we are a sub-group
- wSubGroupID = wGroupID + 1;
-
- // check if on that id is not group of the same or greater level, if yes, try next
- while (CheckServerID(wSubGroupID, 0) && (getServListGroupLevel(wSubGroupID) >= wSubGroupLevel))
- wSubGroupID++;
-
- if (!CheckServerID(wSubGroupID, 0)) { // the next id is free, so create our group with that id
- cookie_servlist_action *ack;
- DWORD dwCookie;
- char *szSubGroupItem = (char*)SAFE_MALLOC(mir_strlen(szSubGroupName) + wSubGroupLevel + 1);
-
- if (szSubGroupItem) {
- int i;
-
- for (i = 0; i < wSubGroupLevel; i++)
- szSubGroupItem[i] = '>';
-
- mir_strcpy(szSubGroupItem + wSubGroupLevel, szSubGroupName);
- szSubGroupItem[mir_strlen(szSubGroupName) + wSubGroupLevel] = '\0';
- SAFE_FREE((void**)&szSubGroupName);
- // check and create unique group name (Miranda does allow more subgroups with the same name!)
- szSubGroupItem = getServListUniqueGroupName(szSubGroupItem, TRUE);
-
- if (ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action))) { // we have cookie good, go on
- debugLogA("Server-List: Creating sub-group \"%s\", parent group \"%s\".", szSubGroupItem, szGroup);
-
- ReserveServerID(wSubGroupID, SSIT_GROUP, 0);
-
- ack->wGroupId = wSubGroupID;
- ack->szGroupName = szSubGroupItem; // we need that name
- ack->szGroup = szSubGroup;
- ack->dwAction = SSA_GROUP_ADD;
- dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, 0, ack);
-
- icq_sendServerGroup(dwCookie, ICQ_LISTS_ADDTOLIST, ack->wGroupId, szSubGroupItem, nullptr, 0, SSOF_BEGIN_OPERATION);
- return CALLBACK_RESULT_CONTINUE;
- }
- SAFE_FREE((void**)&szSubGroupItem);
- }
- }
- // we failed to create sub-group give parent groupid
- icq_LogMessage(LOG_ERROR, LPGEN("Failed to create the correct sub-group, the using closest parent group."));
-
- servlistPendingRemoveGroup(szSubGroup, wGroupID, PENDING_RESULT_FAILED);
-
- SAFE_FREE((void**)&szSubGroupName);
- SAFE_FREE((void**)&szSubGroup);
- return CALLBACK_RESULT_CONTINUE;
-}
-
-
-int CIcqProto::servlistCreateGroup_Ready(const char *szGroup, WORD groupID, LPARAM, int nResult)
-{
- WORD wGroupID = 0;
-
- if (nResult == PENDING_RESULT_PURGE)
- return CALLBACK_RESULT_CONTINUE;
-
- if (wGroupID = getServListGroupLinkID(szGroup)) { // the path is known, continue the process
- servlistPendingRemoveGroup(szGroup, wGroupID, PENDING_RESULT_SUCCESS);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- if (!strstrnull(szGroup, "\\") || m_bSsiSimpleGroups) { // a root group can be simply created without problems; simple groups are mapped directly
- cookie_servlist_action* ack;
- DWORD dwCookie;
-
- if (ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action))) { // we have cookie good, go on
- debugLogA("Server-List: Creating root group \"%s\".", szGroup);
-
- ack->wGroupId = GenerateServerID(SSIT_GROUP, 0);
- ack->szGroup = null_strdup(szGroup); // we need that name
- // check if the groupname is unique - just to be sure, Miranda should handle that!
- ack->szGroupName = getServListUniqueGroupName(ack->szGroup, FALSE);
- ack->dwAction = SSA_GROUP_ADD;
- dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, 0, ack);
-
- icq_sendServerGroup(dwCookie, ICQ_LISTS_ADDTOLIST, ack->wGroupId, ack->szGroup, nullptr, 0, SSOF_BEGIN_OPERATION);
-
- return CALLBACK_RESULT_POSTPONE;
- }
- }
- else { // this is a sub-group
- char *szSub = null_strdup(szGroup); // create subgroup, recursive, event-driven, possibly relocate
- char *szLast = strrchr(szSub, '\\') + 1;
- szLast[-1] = '\0';
-
- // make parent group id
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (ack) {
- ack->szGroupName = null_strdup(szLast); // groupname
- servlistCreateGroup(szSub, (LPARAM)ack, &CIcqProto::servlistCreateGroup_gotParentGroup);
- SAFE_FREE((void**)&szSub);
-
- return CALLBACK_RESULT_POSTPONE;
- }
-
- SAFE_FREE((void**)&szSub);
- }
-
- servlistPendingRemoveGroup(szGroup, groupID, PENDING_RESULT_FAILED);
- return CALLBACK_RESULT_CONTINUE;
-}
-
-// create group with this path, a bit complex task
-// this supposes that all server groups are known
-void CIcqProto::servlistCreateGroup(const char *szGroupPath, LPARAM param, PENDING_GROUP_CALLBACK callback)
-{
- char *szGroup = (char*)szGroupPath;
-
- if (!mir_strlen(szGroup))
- szGroup = DEFAULT_SS_GROUP;
-
- servlistPendingAddGroup(szGroup, 0, 0, &CIcqProto::servlistCreateGroup_Ready, TRUE, param, callback);
-}
-
-/*****************************************
-*
-* --- Server-List Operations ---
-*
-*/
-
-int CIcqProto::servlistAddContact_gotGroup(const char*, WORD wGroupID, LPARAM lParam, int nResult)
-{
- cookie_servlist_action* ack = (cookie_servlist_action*)lParam;
- if (ack)
- SAFE_FREE(&ack->szGroup);
-
- if (nResult == PENDING_RESULT_PURGE) { // only cleanup
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- if (!ack || !wGroupID) { // something went wrong
- if (ack)
- servlistPendingRemoveContact(ack->hContact, 0, wGroupID, PENDING_RESULT_FAILED);
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- WORD wItemID = getWord(ack->hContact, DBSETTING_SERVLIST_ID, 0);
- if (wItemID) {
- // Only add the contact if it doesnt already have an ID
- servlistPendingRemoveContact(ack->hContact, wItemID, wGroupID, PENDING_RESULT_SUCCESS);
- debugLogA("Failed to add contact to server side list (%s)", "already there");
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- wItemID = GenerateServerID(SSIT_ITEM, 0);
-
- ack->dwAction = SSA_CONTACT_ADD;
- ack->wGroupId = wGroupID;
- ack->wContactId = wItemID;
-
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, ack->hContact, ack);
-
- icq_sendServerContact(ack->hContact, dwCookie, ICQ_LISTS_ADDTOLIST, wGroupID, wItemID, SSOP_ITEM_ACTION | SSOF_CONTACT | SSOF_BEGIN_OPERATION, 400, nullptr);
-
- return CALLBACK_RESULT_CONTINUE;
-}
-
-// Need to be called when Pending Contact is active
-int CIcqProto::servlistAddContact_Ready(MCONTACT hContact, WORD, WORD, LPARAM lParam, int nResult)
-{
- cookie_servlist_action* ack = (cookie_servlist_action*)lParam;
-
- if (nResult == PENDING_RESULT_PURGE) { // removing obsolete items, just free the memory
- SAFE_FREE((void**)&ack->szGroup);
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- WORD wItemID = getWord(ack->hContact, DBSETTING_SERVLIST_ID, 0);
-
- if (wItemID) { // Only add the contact if it doesn't already have an ID
- servlistPendingRemoveContact(ack->hContact, wItemID, getWord(hContact, DBSETTING_SERVLIST_GROUP, 0), PENDING_RESULT_SUCCESS);
- debugLogA("Failed to add contact to server side list (%s)", "already there");
- SAFE_FREE((void**)&ack->szGroup);
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- // obtain a correct groupid first
- servlistCreateGroup(ack->szGroup, lParam, &CIcqProto::servlistAddContact_gotGroup);
-
- return CALLBACK_RESULT_POSTPONE;
-}
-
-// Called when contact should be added to server list, if group does not exist, create one
-void CIcqProto::servlistAddContact(MCONTACT hContact, const char *pszGroup)
-{
- // Get UID
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid)) { // Could not do anything without uid
- debugLogA("Failed to add contact to server side list (%s)", "no UID");
- return;
- }
-
- cookie_servlist_action* ack;
- if (!(ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)))) { // Could not do anything without cookie
- debugLogA("Failed to add contact to server side list (%s)", "malloc failed");
- return;
- }
-
- ack->hContact = hContact;
- ack->szGroup = null_strdup(pszGroup);
- // call thru pending operations - makes sure the contact is ready to be added
- servlistPendingAddContact(hContact, 0, 0, (LPARAM)ack, &CIcqProto::servlistAddContact_Ready, TRUE);
-}
-
-int CIcqProto::servlistRemoveContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult)
-{
- WORD wGroupID;
- WORD wItemID;
- cookie_servlist_action* ack = (cookie_servlist_action*)lParam;
- DWORD dwCookie;
-
- if (nResult == PENDING_RESULT_PURGE) {
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- // Get the contact's group ID
- if (!(wGroupID = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0))) { // Could not find a usable group ID
- servlistPendingRemoveContact(hContact, contactID, groupID, PENDING_RESULT_FAILED);
-
- debugLogA("Failed to remove contact from server side list (%s)", "no group ID");
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- // Get the contact's item ID
- if (!(wItemID = getWord(hContact, DBSETTING_SERVLIST_ID, 0))) { // Could not find usable item ID
- servlistPendingRemoveContact(hContact, contactID, wGroupID, PENDING_RESULT_FAILED);
-
- debugLogA("Failed to remove contact from server side list (%s)", "no item ID");
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- ack->dwAction = SSA_CONTACT_REMOVE;
- ack->hContact = hContact;
- ack->wGroupId = wGroupID;
- ack->wContactId = wItemID;
-
- dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, hContact, ack);
-
- icq_sendServerContact(hContact, dwCookie, ICQ_LISTS_REMOVEFROMLIST, wGroupID, wItemID, SSOP_ITEM_ACTION | SSOF_CONTACT | SSOF_BEGIN_OPERATION, 400, nullptr);
-
- return CALLBACK_RESULT_POSTPONE;
-}
-
-// Called when contact should be removed from server list, remove group if it remain empty
-void CIcqProto::servlistRemoveContact(MCONTACT hContact)
-{
- // Get UID
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid)) {
- // Could not do anything without uid
- debugLogA("Failed to remove contact from server side list (%s)", "no UID");
- return;
- }
-
- cookie_servlist_action* ack;
- if (!(ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)))) { // Could not do anything without cookie
- debugLogA("Failed to remove contact from server side list (%s)", "malloc failed");
- return;
- }
-
- ack->hContact = hContact;
- // call thru pending operations - makes sure the contact is ready to be removed
- servlistPendingAddContact(hContact, 0, 0, (LPARAM)ack, &CIcqProto::servlistRemoveContact_Ready, TRUE);
-}
-
-
-int CIcqProto::servlistMoveContact_gotTargetGroup(const char *szGroup, WORD wNewGroupID, LPARAM lParam, int nResult)
-{
- cookie_servlist_action *ack = (cookie_servlist_action*)lParam;
- if (ack)
- SAFE_FREE(&ack->szGroup);
-
- if (nResult == PENDING_RESULT_PURGE) { // removing obsolete items, just free the memory
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- if (!ack || !wNewGroupID || !ack->hContact) { // something went wrong
- if (ack)
- servlistPendingRemoveContact(ack->hContact, 0, 0, PENDING_RESULT_FAILED);
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- WORD wItemID = getWord(ack->hContact, DBSETTING_SERVLIST_ID, 0);
- WORD wGroupID = getWord(ack->hContact, DBSETTING_SERVLIST_GROUP, 0);
-
- if (!wItemID) { // We have no ID, so try to simply add the contact to serv-list
- debugLogA("Unable to move contact (no ItemID) -> trying to add");
- // we know the GroupID, so directly call add
- return servlistAddContact_gotGroup(szGroup, wNewGroupID, lParam, nResult);
- }
-
- if (wGroupID == wNewGroupID) { // Only move the contact if it had different GroupID
- servlistPendingRemoveContact(ack->hContact, wItemID, wNewGroupID, PENDING_RESULT_SUCCESS);
- debugLogA("Contact not moved to group on server side list (same Group)");
- return CALLBACK_RESULT_CONTINUE;
- }
-
- ack->szGroupName = nullptr;
- ack->dwAction = SSA_CONTACT_SET_GROUP;
- ack->wGroupId = wGroupID;
- ack->wContactId = wItemID;
- ack->wNewContactId = GenerateServerID(SSIT_ITEM, 0); // icq5 recreates also this, imitate
- ack->wNewGroupId = wNewGroupID;
- ack->lParam = 0; // we use this as a sign
-
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, ack->hContact, ack);
- DWORD dwCookie2 = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, ack->hContact, ack);
- {
- // imitate icq5, previously here was different order, but AOL changed and it ceased to work
- void *doubleObject = nullptr;
-
- icq_sendServerContact(ack->hContact, dwCookie2, ICQ_LISTS_ADDTOLIST, wNewGroupID, ack->wNewContactId, SSO_CONTACT_SETGROUP | SSOF_BEGIN_OPERATION, 500, &doubleObject);
- icq_sendServerContact(ack->hContact, dwCookie, ICQ_LISTS_REMOVEFROMLIST, wGroupID, wItemID, SSO_CONTACT_SETGROUP | SSOF_BEGIN_OPERATION, 500, &doubleObject);
- }
- return CALLBACK_RESULT_CONTINUE;
-}
-
-int CIcqProto::servlistMoveContact_Ready(MCONTACT, WORD contactID, WORD groupID, LPARAM lParam, int nResult)
-{
- cookie_servlist_action *ack = (cookie_servlist_action*)lParam;
-
- if (nResult == PENDING_RESULT_PURGE) { // removing obsolete items, just free the memory
- SAFE_FREE(&ack->szGroup);
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- WORD wItemID = getWord(ack->hContact, DBSETTING_SERVLIST_ID, 0);
- WORD wGroupID = getWord(ack->hContact, DBSETTING_SERVLIST_GROUP, 0);
-
- if (!wGroupID && wItemID) { // Only move the contact if it had an GroupID
- servlistPendingRemoveContact(ack->hContact, contactID, groupID, PENDING_RESULT_FAILED);
-
- debugLogA("Failed to move contact to group on server side list (%s)", "no Group");
- SAFE_FREE(&ack->szGroup);
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- // obtain a correct target groupid first
- servlistCreateGroup(ack->szGroup, lParam, &CIcqProto::servlistMoveContact_gotTargetGroup);
- return CALLBACK_RESULT_POSTPONE;
-}
-
-// Called when contact should be moved from one group to another, create new, remove empty
-void CIcqProto::servlistMoveContact(MCONTACT hContact, const char *pszNewGroup)
-{
- if (!hContact) return; // we do not move us, caused our uin was wrongly added to list
-
- // Get UID
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid)) { // Could not do anything without uin
- debugLogA("Failed to move contact to group on server side list (%s)", "no UID");
- return;
- }
-
- if ((pszNewGroup != nullptr) && (pszNewGroup[0] != '\0') && !getCListGroupExists(pszNewGroup)) { // the contact moved to non existing group, do not do anything: MetaContact hack
- debugLogA("Contact not moved - probably hiding by MetaContacts.");
- return;
- }
-
- if (!getWord(hContact, DBSETTING_SERVLIST_ID, 0)) /// FIXME:::: this should be in _ready
- { // the contact is not stored on the server, check if we should try to add
- if (!getByte("ServerAddRemove", DEFAULT_SS_ADDSERVER) ||
- db_get_b(hContact, "CList", "Hidden", 0))
- return;
- }
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
-
- if (!ack) { // Could not do anything without cookie
- debugLogA("Failed to add contact to server side list (%s)", "malloc failed");
- return;
- }
- else {
- ack->hContact = hContact;
- ack->szGroup = null_strdup(pszNewGroup);
- // call thru pending operations - makes sure the contact is ready to be moved
- servlistPendingAddContact(hContact, 0, 0, (LPARAM)ack, &CIcqProto::servlistMoveContact_Ready, TRUE);
- return;
- }
-}
-
-
-int CIcqProto::servlistUpdateContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult)
-{
- cookie_servlist_action *ack = (cookie_servlist_action*)lParam;
-
- if (nResult == PENDING_RESULT_PURGE) { // removing obsolete items, just free the memory
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
- WORD wItemID;
- WORD wGroupID;
-
- // Get the contact's group ID
- if (!(wGroupID = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0))) {
- servlistPendingRemoveContact(hContact, contactID, groupID, PENDING_RESULT_FAILED);
- // Could not find a usable group ID
- debugLogA("Failed to update contact's details on server side list (%s)", "no group ID");
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- // Get the contact's item ID
- if (!(wItemID = getWord(hContact, DBSETTING_SERVLIST_ID, 0))) {
- servlistPendingRemoveContact(hContact, contactID, wGroupID, PENDING_RESULT_FAILED);
- // Could not find usable item ID
- debugLogA("Failed to update contact's details on server side list (%s)", "no item ID");
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- ack->dwAction = SSA_CONTACT_UPDATE;
- ack->wContactId = wItemID;
- ack->wGroupId = wGroupID;
- ack->hContact = hContact;
-
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, hContact, ack);
-
- // There is no need to send ICQ_LISTS_CLI_MODIFYSTART or
- // ICQ_LISTS_CLI_MODIFYEND when just changing nick name
- icq_sendServerContact(hContact, dwCookie, ICQ_LISTS_UPDATEGROUP, wGroupID, wItemID, SSOP_ITEM_ACTION | SSOF_CONTACT, 400, nullptr);
-
- return CALLBACK_RESULT_POSTPONE;
-}
-
-
-// Is called when a contact' details has been changed locally to update
-// the server side details.
-void CIcqProto::servlistUpdateContact(MCONTACT hContact)
-{
- // Get UID
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid)) {
- // Could not set nickname on server without uid
- debugLogA("Failed to update contact's details on server side list (%s)", "no UID");
- return;
- }
-
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (!ack) {
- // Could not allocate cookie - use old fake
- debugLogA("Failed to update contact's details on server side list (%s)", "malloc failed");
- return;
- }
-
- ack->hContact = hContact;
- // call thru pending operations - makes sure the contact is ready to be updated
- servlistPendingAddContact(hContact, 0, 0, (LPARAM)ack, &CIcqProto::servlistUpdateContact_Ready, TRUE);
-}
-
-int CIcqProto::servlistRenameGroup_Ready(const char *szGroup, WORD wGroupID, LPARAM lParam, int nResult)
-{
- cookie_servlist_action *ack = (cookie_servlist_action*)lParam;
-
- if (nResult == PENDING_RESULT_PURGE) { // only cleanup
- if (ack)
- SAFE_FREE(&ack->szGroupName);
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- if (!ack || !wGroupID) { // something went wrong
- servlistPendingRemoveGroup(szGroup, wGroupID, PENDING_RESULT_FAILED);
-
- if (ack) SAFE_FREE(&ack->szGroupName);
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- void *groupData;
- int groupSize;
- if (groupData = collectBuddyGroup(wGroupID, &groupSize)) {
- ack->dwAction = SSA_GROUP_RENAME;
- ack->wGroupId = wGroupID;
- ack->szGroup = null_strdup(szGroup); // we need this name
- // check if the new name is unique, create unique groupname if necessary
- ack->szGroupName = getServListUniqueGroupName(ack->szGroupName, TRUE);
-
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack);
-
- icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, wGroupID, ack->szGroupName, groupData, groupSize, 0);
- SAFE_FREE(&groupData);
- }
- return CALLBACK_RESULT_POSTPONE;
-}
-
-
-void CIcqProto::servlistRenameGroup(char *szGroup, WORD wGroupId, char *szNewGroup)
-{
- char *szNewGroupName;
- int nGroupLevel = getServListGroupLevel(wGroupId);
-
- if (nGroupLevel == -1) return; // we failed to prepare group
-
- if (!m_bSsiSimpleGroups) {
- char *szGroupName = szGroup;
- int i = nGroupLevel;
- while (i) { // find correct part of grouppath
- szGroupName = strstrnull(szGroupName, "\\");
- if (!szGroupName) return; // failed to get correct part of the grouppath
- szGroupName++;
- i--;
- }
- szNewGroupName = szNewGroup;
- i = nGroupLevel;
- while (i) { // find correct part of new grouppath
- szNewGroupName = strstrnull(szNewGroupName, "\\");
- if (!szNewGroupName) return; // failed to get correct part of the new grouppath
- szNewGroupName++;
- i--;
- }
- // truncate possible sub-groups
- char *szLast = strstrnull(szGroupName, "\\");
- if (szLast)
- szLast[0] = '\0';
- szLast = strstrnull(szNewGroupName, "\\");
- if (szLast)
- szLast[0] = '\0';
-
- // this group was not changed, nothing to rename
- if (!mir_strcmp(szGroupName, szNewGroupName)) return;
-
- szGroupName = szNewGroupName;
- szNewGroupName = (char*)SAFE_MALLOC(mir_strlen(szGroupName) + 1 + nGroupLevel);
- if (!szNewGroupName) return; // Failure
-
- for (i = 0; i < nGroupLevel; i++) { // create level prefix
- szNewGroupName[i] = '>';
- }
- mir_strcat(szNewGroupName, szGroupName);
- }
- else // simple groups do not require any conversion
- szNewGroupName = null_strdup(szNewGroup);
-
- cookie_servlist_action* ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (!ack) { // cookie failed
- debugLogA("Error: Failed to allocate cookie");
-
- SAFE_FREE(&szNewGroupName);
- return;
- }
- // store new group name for future use
- ack->szGroupName = szNewGroupName;
- // call thru pending operations - makes sure the group is ready for rename
- servlistPendingAddGroup(szGroup, wGroupId, (LPARAM)ack, &CIcqProto::servlistRenameGroup_Ready, TRUE);
-}
-
-int CIcqProto::servlistRemoveGroup_Ready(const char *szGroup, WORD groupID, LPARAM lParam, int nResult)
-{
- cookie_servlist_action *ack = (cookie_servlist_action*)lParam;
-
- if (nResult == PENDING_RESULT_PURGE) { // only cleanup
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
- WORD wGroupID = getServListGroupLinkID(szGroup);
- char *szGroupName;
-
- if (wGroupID && (szGroupName = getServListGroupName(wGroupID))) { // the group is valid, check if it is empty
- void *groupData = collectBuddyGroup(wGroupID, nullptr);
-
- if (groupData) { // the group is not empty, cannot delete
- SAFE_FREE(&groupData);
- SAFE_FREE(&szGroupName);
- // end operation
- servlistPendingRemoveGroup(szGroup, wGroupID, PENDING_RESULT_SUCCESS);
- // cleanup
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
- }
-
- if (!CheckServerID((WORD)(wGroupID + 1), 0) || getServListGroupLevel((WORD)(wGroupID + 1)) == 0) { // is next id an sub-group, if yes, we cannot delete this group
- ack->dwAction = SSA_GROUP_REMOVE;
- ack->wContactId = 0;
- ack->wGroupId = wGroupID;
- ack->hContact = NULL;
- ack->szGroup = null_strdup(szGroup); // we need that name
- ack->szGroupName = szGroupName;
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, 0, ack);
-
- icq_sendServerGroup(dwCookie, ICQ_LISTS_REMOVEFROMLIST, ack->wGroupId, ack->szGroupName, nullptr, 0, 0);
- }
- return CALLBACK_RESULT_POSTPONE;
- }
- // end operation
- servlistPendingRemoveGroup(szGroup, groupID, PENDING_RESULT_SUCCESS);
- // cleanup
- SAFE_FREE((void**)&ack);
- return CALLBACK_RESULT_CONTINUE;
-}
-
-
-void CIcqProto::servlistRemoveGroup(const char *szGroup, WORD wGroupId)
-{
- if (!szGroup) return;
-
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (!ack) { // cookie failed
- debugLogA("Error: Failed to allocate cookie");
- return;
- }
-
- // call thru pending operations - makes sure the group is ready for removal
- servlistPendingAddGroup(szGroup, wGroupId, (LPARAM)ack, &CIcqProto::servlistRemoveGroup_Ready, TRUE);
-}
-
-void CIcqProto::resetServContactAuthState(MCONTACT hContact)
-{
- WORD wContactId = getWord(hContact, DBSETTING_SERVLIST_ID, 0);
- WORD wGroupId = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0);
-
- if (wContactId && wGroupId) {
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (ack) { // we have cookie good, go on
- ack->hContact = hContact;
- ack->wContactId = wContactId;
- ack->wGroupId = wGroupId;
- ack->dwAction = SSA_CONTACT_FIX_AUTH;
-
- DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, 0, hContact, ack);
-
- {
- void *doubleObject = nullptr;
-
- icq_sendServerContact(hContact, dwCookie, ICQ_LISTS_REMOVEFROMLIST, wGroupId, wContactId, SSO_CONTACT_FIXAUTH | SSOF_BEGIN_OPERATION | SSOF_END_OPERATION, 200, &doubleObject);
- delSetting(hContact, DBSETTING_METAINFO_TOKEN);
- delSetting(hContact, DBSETTING_METAINFO_TIME);
- delSetting(hContact, DBSETTING_SERVLIST_DATA);
- icq_sendServerContact(hContact, dwCookie, ICQ_LISTS_ADDTOLIST, wGroupId, wContactId, SSO_CONTACT_FIXAUTH | SSOF_BEGIN_OPERATION | SSOF_END_OPERATION, 200, &doubleObject);
- }
- }
- else debugLogA("Error: Failed to allocate cookie");
- }
-}
-
-/*****************************************
-*
-* --- Miranda Contactlist Hooks ---
-*
-*/
-
-int CIcqProto::ServListDbSettingChanged(WPARAM hContact, LPARAM lParam)
-{
- DBCONTACTWRITESETTING* cws = (DBCONTACTWRITESETTING*)lParam;
-
- // TODO: Queue changes that occur while offline
- if (!icqOnline() || !m_bSsiEnabled || bIsSyncingCL)
- return 0;
-
- if (!strcmp(cws->szModule, "CList")) {
- // Has contact been renamed?
- if (!strcmp(cws->szSetting, "MyHandle") && getByte("StoreServerDetails", DEFAULT_SS_STORE))
- servlistUpdateContact(hContact); // Update contact's details in server-list
-
- // Has contact been moved to another group?
- if (!strcmp(cws->szSetting, "Group") && getByte("StoreServerDetails", DEFAULT_SS_STORE)) {
- char* szNewGroup = getContactCListGroup(hContact); // Read group from DB
- SAFE_FREE(&szNewGroup);
- }
- }
- else if (!strcmp(cws->szModule, "UserInfo")) {
- // Update contact's details in server-list
- if (!strcmp(cws->szSetting, "MyNotes") && getByte("StoreServerDetails", DEFAULT_SS_STORE))
- servlistUpdateContact(hContact);
- }
-
- return 0;
-}
-
-
-void CIcqProto::OnContactDeleted(MCONTACT hContact)
-{
- DeleteFromContactsCache(hContact);
-
- if (!icqOnline() && m_bSsiEnabled)
- // contact was deleted only locally - retrieve full list on next connect
- setWord(hContact, "SrvRecordCount", 0);
-
- if (!icqOnline() || !m_bSsiEnabled)
- return;
-
- // we need all server contacts on local buddy list
- DWORD dwUIN;
- uid_str szUID;
- if (getContactUid(hContact, &dwUIN, &szUID))
- return;
-
- WORD wContactID = getWord(hContact, DBSETTING_SERVLIST_ID, 0);
- WORD wGroupID = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0);
- WORD wVisibleID = getWord(hContact, DBSETTING_SERVLIST_PERMIT, 0);
- WORD wInvisibleID = getWord(hContact, DBSETTING_SERVLIST_DENY, 0);
- WORD wIgnoreID = getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0);
-
- // Remove from queue for user details request
- icq_DequeueUser(dwUIN);
-
- // Close all opened peer connections
- CloseContactDirectConns(hContact);
-
- if ((wGroupID && wContactID) || wVisibleID || wInvisibleID || wIgnoreID) {
- if (wContactID) // delete contact from server
- servlistRemoveContact(hContact);
-
- if (wVisibleID) // detete permit record
- icq_removeServerPrivacyItem(hContact, dwUIN, szUID, wVisibleID, SSI_ITEM_PERMIT);
-
- if (wInvisibleID) // delete deny record
- icq_removeServerPrivacyItem(hContact, dwUIN, szUID, wInvisibleID, SSI_ITEM_DENY);
-
- if (wIgnoreID) // delete ignore record
- icq_removeServerPrivacyItem(hContact, dwUIN, szUID, wIgnoreID, SSI_ITEM_IGNORE);
- }
-}
-
-
-int CIcqProto::ServListCListGroupChange(WPARAM hContact, LPARAM lParam)
-{
- CLISTGROUPCHANGE *grpchg = (CLISTGROUPCHANGE*)lParam;
-
- if (!icqOnline() || !m_bSsiEnabled || bIsSyncingCL)
- return 0;
-
- // only change server-list if it is allowed
- if (!getByte("StoreServerDetails", DEFAULT_SS_STORE))
- return 0;
-
- if (hContact == NULL) { // change made to group
- if (grpchg->pszNewName == nullptr && grpchg->pszOldName != nullptr) { // group removed
- char *szOldName = make_utf8_string(grpchg->pszOldName);
- WORD wGroupId = getServListGroupLinkID(szOldName);
-
- if (wGroupId) { // the group is known, remove from server
- servlistPostPacket(nullptr, 0, SSO_BEGIN_OPERATION, 100); // start server modifications here
- servlistRemoveGroup(szOldName, wGroupId);
- }
- SAFE_FREE(&szOldName);
- }
- else if (grpchg->pszNewName != nullptr && grpchg->pszOldName != nullptr) { // group renamed
- char *szNewName = make_utf8_string(grpchg->pszNewName);
- char *szOldName = make_utf8_string(grpchg->pszOldName);
- WORD wGroupId = getServListGroupLinkID(szOldName);
-
- if (wGroupId) { // group is known, rename on server
- servlistRenameGroup(szOldName, wGroupId, szNewName);
- }
- SAFE_FREE(&szOldName);
- SAFE_FREE(&szNewName);
- }
- }
- else { // change to contact
- if (IsICQContact(hContact)) { // our contact, fine move on the server as well
- char *szNewName = grpchg->pszNewName ? make_utf8_string(grpchg->pszNewName) : nullptr;
- servlistMoveContact(hContact, szNewName);
- SAFE_FREE(&szNewName);
- }
- }
- return 0;
-}
diff --git a/protocols/IcqOscarJ/src/icq_servlist.h b/protocols/IcqOscarJ/src/icq_servlist.h
deleted file mode 100644
index 081b509469..0000000000
--- a/protocols/IcqOscarJ/src/icq_servlist.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#ifndef __ICQ_SERVLIST_H
-#define __ICQ_SERVLIST_H
-
-// actions:
-#define SSA_CHECK_ROSTER 0 // request serv-list
-#define SSA_VISIBILITY 1 // update visibility
-#define SSA_CONTACT_UPDATE 2 // update contact's details
-#define SSA_GROUP_RENAME 5 // rename group
-#define SSA_PRIVACY_ADD 0xA // add privacy item
-#define SSA_PRIVACY_REMOVE 0xB // remove privacy item
-#define SSA_CONTACT_ADD 0x10 // add contact w/o auth
-#define SSA_CONTACT_SET_GROUP 0x12 // move to group
-#define SSA_CONTACT_REMOVE 0x13 // delete contact
-#define SSA_CONTACT_FIX_AUTH 0x40 // reuploading contact for auth re-request
-#define SSA_GROUP_ADD 0x15 // create group
-#define SSA_GROUP_REMOVE 0x16 // delete group
-#define SSA_GROUP_UPDATE 0x17 // update group
-#define SSA_SERVLIST_ACK 0x20 // send proto ack only (UploadUI)
-#define SSA_SETAVATAR 0x30
-#define SSA_REMOVEAVATAR 0x31
-#define SSA_IMPORT 7
-#define SSA_ACTION_GROUP 0x80 // grouped action
-
-struct CIcqProto;
-// callback prototypes for pending operation mechanism:
-typedef int(__cdecl CIcqProto::*PENDING_GROUP_CALLBACK)(const char* pszGroup, WORD wGroupId, LPARAM lParam, int nResult);
-typedef int(__cdecl CIcqProto::*PENDING_CONTACT_CALLBACK)(MCONTACT hContact, WORD wContactId, WORD wGroupId, LPARAM lParam, int nResult);
-
-// cookie struct for SSI actions
-struct cookie_servlist_action
-{
- MCONTACT hContact;
- char *szGroup;
- WORD wContactId;
- WORD wGroupId;
- char *szGroupName;
- WORD wNewContactId;
- WORD wNewGroupId;
- int dwAction;
- LPARAM lParam;
- int dwGroupCount;
- cookie_servlist_action **pGroupItems;
-};
-
-// server id type groups
-#define SSIT_ITEM 0x00000000
-#define SSIT_GROUP 0x00010000
-
-// server id flags
-#define SSIF_UNHANDLED 0x01000000
-
-
-// pending operations
-#define PENDING_RESULT_SUCCESS 0x00
-#define PENDING_RESULT_INLINE 0x01
-#define PENDING_RESULT_FAILED 0x0F
-#define PENDING_RESULT_PURGE 0x10
-
-// serv-list update board
-#define SSOG_SINGLE 0x00010000
-#define SSOG_DOUBLE 0x00020000
-
-#define SSOF_CONTACT 0x00800000
-#define SSOF_BEGIN_OPERATION 0x00100000
-#define SSOF_END_OPERATION 0x00200000
-#define SSOF_IMPORT_OPERATION 0x00400000
-
-#define SSOP_ITEM_ACTION 0x01000000 | SSOG_SINGLE
-// SSA_PRIVACY_ADD
-// SSA_CONTACT_ADD
-// SSA_CONTACT_UPDATE
-// SSA_VISIBILITY
-// SSA_PRIVACY_REMOVE
-// SSA_CONTACT_REMOVE
-// SSA_SETAVATAR
-// SSA_REMOVEAVATAR
-#define SSOP_GROUP_ACTION 0x02000000 | SSOG_SINGLE
-// SSA_GROUP_ADD
-// SSA_GROUP_RENAME
-// SSA_GROUP_UPDATE
-// SSA_GROUP_REMOVE
-#define SSO_CONTACT_SETGROUP 0x04000000 | SSOG_DOUBLE
-// SSA_CONTACT_SET_GROUP
-#define SSO_CONTACT_FIXAUTH 0x06000000 | SSOG_DOUBLE
-// SSA_CONTACT_FIX_AUTH
-
-#define SSO_BEGIN_OPERATION 0x80000000
-#define SSO_END_OPERATION 0x40000000
-
-#define SSOF_SEND_DIRECTLY 0x10000000
-
-#define SSOF_ACTIONMASK 0x0000FFFF
-#define SSOF_GROUPINGMASK 0x0F0FFFFF
-
-
-#define MAX_SERVLIST_PACKET_ITEMS 200
-
-// server-list request handler item
-struct servlistgroupitem
-{ // generic parent
- DWORD dwOperation;
- cookie_servlist_action* cookie;
- icq_packet packet;
- // perhaps add some dummy bytes
-};
-
-struct servlistgroupitemdouble : public servlistgroupitem
-{
- icq_packet packet2;
- WORD wAction2;
-};
-
-struct ssiqueueditems
-{
- time_t tAdded;
- int dwTimeout;
- int nItems;
- servlistgroupitem* pItems[MAX_SERVLIST_PACKET_ITEMS];
-};
-
-
-// cookie structs for pending records
-struct servlistpendingoperation
-{
- DWORD flags;
- PENDING_GROUP_CALLBACK callback;
- LPARAM param;
-};
-
-struct servlistpendingitem
-{
- int nType;
- MCONTACT hContact;
- char* szGroup;
- WORD wContactID;
- WORD wGroupID;
-
- servlistpendingoperation* operations;
- int operationsCount;
-};
-
-
-#endif /* __ICQ_SERVLIST_H */
diff --git a/protocols/IcqOscarJ/src/icq_uploadui.cpp b/protocols/IcqOscarJ/src/icq_uploadui.cpp
deleted file mode 100644
index 8b35afbed6..0000000000
--- a/protocols/IcqOscarJ/src/icq_uploadui.cpp
+++ /dev/null
@@ -1,873 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Implements Manage Server List dialog
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-static int bListInit = 0;
-static HANDLE hItemAll;
-static int dwUploadDelay = 1000; // initial setting, it is too low for icq server but good for short updates
-
-static HWND hwndUploadContacts = nullptr;
-static const UINT settingsControls[] = { IDOK };
-
-static WORD *pwGroupIds = nullptr;
-static int cbGroupIds = 0;
-
-// Init default clist options
-static void ResetCListOptions(HWND hwndList)
-{
- SetWindowLongPtr(hwndList, GWL_STYLE, GetWindowLongPtr(hwndList, GWL_STYLE) | CLS_SHOWHIDDEN);
- SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM)TRUE, 0);
-}
-
-// Selects the "All contacts" checkbox if all other list entries
-// are selected, deselects it if not.
-static void UpdateAllContactsCheckmark(HWND hwndList, CIcqProto* ppro, HANDLE phItemAll)
-{
- int check = 1;
-
- for (auto &hContact : ppro->AccContacts()) {
- HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, hContact, 0);
- if (hItem) {
- if (!SendMessage(hwndList, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) { // if any of our contacts is unchecked, uncheck all contacts as well
- check = 0;
- break;
- }
- }
- }
-
- SendMessage(hwndList, CLM_SETCHECKMARK, (WPARAM)phItemAll, check);
-}
-
-// Loop over all contacts and update the checkmark
-// that indicates wether or not they are already uploaded
-static int UpdateCheckmarks(HWND hwndList, CIcqProto* ppro, HANDLE phItemAll)
-{
- int bAll = 1;
- bListInit = 1; // lock CLC events
-
- for (auto &hContact : ppro->AccContacts()) {
- HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, hContact, 0);
- if (hItem) {
- if (ppro->getWord(hContact, DBSETTING_SERVLIST_ID, 0))
- SendMessage(hwndList, CLM_SETCHECKMARK, (WPARAM)hItem, 1);
- else
- bAll = 0;
- }
- }
-
- // Update the "All contacts" checkmark
- if (phItemAll)
- SendMessage(hwndList, CLM_SETCHECKMARK, (WPARAM)phItemAll, bAll);
-
- bListInit = 0;
-
- return bAll;
-}
-
-static void DeleteOtherContactsFromControl(HWND hCtrl, CIcqProto* ppro)
-{
- for (auto &hContact : Contacts()) {
- HANDLE hItem = (HANDLE)SendMessage(hCtrl, CLM_FINDCONTACT, hContact, 0);
- if (hItem)
- if (!ppro->IsICQContact(hContact))
- SendMessage(hCtrl, CLM_DELETEITEM, (WPARAM)hItem, 0);
- }
-}
-
-static void AppendToUploadLog(HWND hwndDlg, const char *fmt, ...)
-{
- va_list va;
- char szText[1024];
- int iItem;
-
- va_start(va, fmt);
- mir_vsnprintf(szText, sizeof(szText), fmt, va);
- va_end(va);
-
- iItem = ListBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_LOG), szText);
- SendDlgItemMessage(hwndDlg, IDC_LOG, LB_SETTOPINDEX, iItem, 0);
-}
-
-static void DeleteLastUploadLogLine(HWND hwndDlg)
-{
- SendDlgItemMessage(hwndDlg, IDC_LOG, LB_DELETESTRING, SendDlgItemMessage(hwndDlg, IDC_LOG, LB_GETCOUNT, 0, 0) - 1, 0);
-}
-
-static void GetLastUploadLogLine(HWND hwndDlg, char *szBuf, size_t cbBuf)
-{
- WCHAR str[MAX_PATH];
- SendDlgItemMessageW(hwndDlg, IDC_LOG, LB_GETTEXT, SendDlgItemMessage(hwndDlg, IDC_LOG, LB_GETCOUNT, 0, 0) - 1, (LPARAM)str);
- make_utf8_string_static(str, szBuf, cbBuf);
-}
-
-static int GroupEnumIdsEnumProc(const char *szSetting, void *lParam)
-{
- // it is probably server group
- if (szSetting && mir_strlen(szSetting) < 5) {
- char val[MAX_PATH + 2]; // dummy
- if (db_get_static(NULL, (char*)lParam, szSetting, val, MAX_PATH))
- return 0; // this converts all string types to DBVT_ASCIIZ
-
- pwGroupIds = (WORD*)SAFE_REALLOC(pwGroupIds, (cbGroupIds + 1) * sizeof(WORD));
- pwGroupIds[cbGroupIds] = (WORD)strtoul(szSetting, nullptr, 0x10);
- cbGroupIds++;
- }
- return 0;
-}
-
-static void enumServerGroups(CIcqProto* ppro)
-{
- char szModule[MAX_PATH + 9];
- mir_snprintf(szModule, "%s%s", ppro->m_szModuleName, "SrvGroups");
- db_enum_settings(NULL, &GroupEnumIdsEnumProc, szModule, szModule);
-}
-
-static DWORD sendUploadGroup(CIcqProto* ppro, WORD wAction, WORD wGroupId, char* szItemName)
-{
- DWORD dwCookie;
- cookie_servlist_action* ack;
-
- if (ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action))) { // we have cookie good, go on
- ack->wGroupId = wGroupId;
- ack->dwAction = SSA_SERVLIST_ACK;
- dwCookie = ppro->AllocateCookie(CKT_SERVERLIST, wAction, 0, ack);
- ack->lParam = dwCookie;
-
- ppro->icq_sendServerGroup(dwCookie, wAction, ack->wGroupId, szItemName, nullptr, 0, 0);
- return dwCookie;
- }
- return 0;
-}
-
-static DWORD sendUploadBuddy(CIcqProto* ppro, MCONTACT hContact, WORD wAction, DWORD dwUin, char *szUID, WORD wContactId, WORD wGroupId, WORD wItemType)
-{
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (ack == nullptr)
- return 0;
-
- // we have cookie good, go on
- ack->hContact = hContact;
- ack->wContactId = wContactId;
- ack->wGroupId = wGroupId;
- ack->dwAction = SSA_SERVLIST_ACK;
- DWORD dwCookie = ppro->AllocateCookie(CKT_SERVERLIST, wAction, hContact, ack);
- ack->lParam = dwCookie;
-
- if (wItemType == SSI_ITEM_BUDDY)
- ppro->icq_sendServerContact(hContact, dwCookie, wAction, ack->wGroupId, ack->wContactId, SSOP_ITEM_ACTION | SSOF_CONTACT, 500, nullptr);
- else
- ppro->icq_sendSimpleItem(dwCookie, wAction, dwUin, szUID, ack->wGroupId, ack->wContactId, wItemType, SSOP_ITEM_ACTION, 500);
-
- return dwCookie;
-}
-
-static char* getServerResultDesc(int wCode)
-{
- switch (wCode) {
- case 0: return LPGEN("OK");
- case 2: return LPGEN("NOT FOUND");
- case 3: return LPGEN("ALREADY EXISTS");
- case 0xA: return LPGEN("INVALID DATA");
- case 0xC: return LPGEN("LIST FULL");
- default: return LPGEN("FAILED");
- }
-}
-
-#define ACTION_NONE 0
-#define ACTION_ADDBUDDY 1
-#define ACTION_ADDBUDDYAUTH 2
-#define ACTION_REMOVEBUDDY 3
-#define ACTION_ADDGROUP 4
-#define ACTION_REMOVEGROUP 5
-#define ACTION_UPDATESTATE 6
-#define ACTION_MOVECONTACT 7
-#define ACTION_ADDVISIBLE 8
-#define ACTION_REMOVEVISIBLE 9
-#define ACTION_ADDINVISIBLE 10
-#define ACTION_REMOVEINVISIBLE 11
-
-#define STATE_READY 1
-#define STATE_REGROUP 2
-#define STATE_ITEMS 3
-#define STATE_VISIBILITY 5
-#define STATE_CONSOLIDATE 4
-
-#define M_PROTOACK (WM_USER+100)
-#define M_UPLOADMORE (WM_USER+101)
-#define M_INITCLIST (WM_USER+102)
-
-static INT_PTR CALLBACK DlgProcUploadList(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
- CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- static int working;
- static HANDLE hProtoAckHook;
- static int currentSequence;
- static int currentAction;
- static int currentState;
- static MCONTACT hCurrentContact;
- static int lastAckResult = 0;
- static WORD wNewContactId;
- static WORD wNewGroupId;
- static char *szNewGroupName;
- static WORD wNewVisibilityId;
-
- switch (message) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
-
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
- {
- char str[MAX_PATH];
-
- working = 0;
- hProtoAckHook = nullptr;
- currentState = STATE_READY;
-
- ResetCListOptions(GetDlgItem(hwndDlg, IDC_CLIST));
-
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Select contacts you want to store on server."), str, MAX_PATH));
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Ready..."), str, MAX_PATH));
- }
- return TRUE;
-
- // The M_PROTOACK message is received when the
- // server has responded to our last update packet
- case M_PROTOACK:
- {
- int bMulti = 0;
- ACKDATA *ack = (ACKDATA*)lParam;
- char szLastLogLine[MAX_PATH];
- char str[MAX_PATH];
-
- // Is this an ack we are waiting for?
- if (mir_strcmp(ack->szModule, ppro->m_szModuleName))
- break;
-
- if (ack->type == ICQACKTYPE_RATEWARNING) { // we are sending tooo fast, slow down the process
- if (ack->hProcess != (HANDLE)1) break; // check class
- if (ack->lParam == 2 || ack->lParam == 3) { // check status
- GetLastUploadLogLine(hwndDlg, szLastLogLine, MAX_PATH);
- DeleteLastUploadLogLine(hwndDlg);
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Server rate warning -> slowing down the process."), str, MAX_PATH));
- AppendToUploadLog(hwndDlg, szLastLogLine);
-
- dwUploadDelay *= 2;
-
- break;
- }
- if (ack->lParam == 4) dwUploadDelay /= 2; // the rate is ok, turn up
- }
-
- if (ack->type != ICQACKTYPE_SERVERCLIST)
- break;
-
- if ((INT_PTR)ack->hProcess != currentSequence)
- break;
-
- lastAckResult = ack->result == ACKRESULT_SUCCESS ? 0 : 1;
-
- switch (currentAction) {
- case ACTION_ADDBUDDY:
- if (ack->result == ACKRESULT_SUCCESS) {
- ppro->setByte(hCurrentContact, "Auth", 0);
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_ID, wNewContactId);
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_GROUP, wNewGroupId);
- break;
- }
- else { // If the server refused to add the contact without authorization,
- // we try again _with_ authorization TLV
- ppro->setByte(hCurrentContact, "Auth", 1);
-
- DWORD dwUIN;
- uid_str szUID;
- if (!ppro->getContactUid(hCurrentContact, &dwUIN, &szUID)) {
- currentAction = ACTION_ADDBUDDYAUTH;
- currentSequence = sendUploadBuddy(ppro, hCurrentContact, ICQ_LISTS_ADDTOLIST, dwUIN, szUID, wNewContactId, wNewGroupId, SSI_ITEM_BUDDY);
- }
-
- return FALSE;
- }
-
- case ACTION_ADDBUDDYAUTH:
- if (ack->result == ACKRESULT_SUCCESS) {
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_ID, wNewContactId);
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_GROUP, wNewGroupId);
- }
- else {
- db_unset(hCurrentContact, ppro->m_szModuleName, "Auth");
- ppro->FreeServerID(wNewContactId, SSIT_ITEM);
- }
- break;
-
- case ACTION_REMOVEBUDDY:
- if (ack->result == ACKRESULT_SUCCESS) { // clear obsolete settings
- ppro->FreeServerID(wNewContactId, SSIT_ITEM);
- db_unset(hCurrentContact, ppro->m_szModuleName, DBSETTING_SERVLIST_ID);
- db_unset(hCurrentContact, ppro->m_szModuleName, DBSETTING_SERVLIST_GROUP);
- db_unset(hCurrentContact, ppro->m_szModuleName, "Auth");
- }
- break;
-
- case ACTION_ADDGROUP:
- if (ack->result == ACKRESULT_SUCCESS) {
- ppro->setServListGroupName(wNewGroupId, szNewGroupName); // add group to list
- ppro->setServListGroupLinkID(szNewGroupName, wNewGroupId); // grouppath is known
-
- int groupSize;
- void *groupData = ppro->collectGroups(&groupSize);
- groupData = SAFE_REALLOC(groupData, groupSize + 2);
- *(((WORD*)groupData) + (groupSize >> 1)) = wNewGroupId; // add this new group id
- groupSize += 2;
-
- cookie_servlist_action *action = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (action) {
- DWORD dwCookie; // we do not use this
-
- action->dwAction = SSA_SERVLIST_ACK;
- dwCookie = ppro->AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, action);
-
- ppro->icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, 0, action->szGroupName, groupData, groupSize, 0);
- }
- SAFE_FREE((void**)&groupData);
- }
- else ppro->FreeServerID(wNewGroupId, SSIT_GROUP);
-
- SAFE_FREE((void**)&szNewGroupName);
- break;
-
- case ACTION_REMOVEGROUP:
- if (ack->result == ACKRESULT_SUCCESS) {
- ppro->FreeServerID(wNewGroupId, SSIT_GROUP);
- ppro->setServListGroupName(wNewGroupId, nullptr); // remove group from list
- ppro->removeGroupPathLinks(wNewGroupId); // grouppath is known
-
- int groupSize;
- void *groupData = ppro->collectGroups(&groupSize);
-
- cookie_servlist_action *action = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
- if (action) {
- DWORD dwCookie; // we do not use this
-
- action->dwAction = SSA_SERVLIST_ACK;
- dwCookie = ppro->AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, action);
-
- ppro->icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, 0, action->szGroupName, groupData, groupSize, 0);
- }
- SAFE_FREE((void**)&groupData);
- }
- break;
-
- case ACTION_UPDATESTATE:
- // do nothing
- break;
-
- case ACTION_MOVECONTACT:
- if (ack->result == ACKRESULT_SUCCESS) {
- ppro->FreeServerID(ppro->getWord(hCurrentContact, DBSETTING_SERVLIST_ID, 0), SSIT_ITEM);
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_ID, wNewContactId);
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_GROUP, wNewGroupId);
- dwUploadDelay *= 2; // we double the delay here (2 packets)
- }
- break;
-
- case ACTION_ADDVISIBLE:
- if (ack->result == ACKRESULT_SUCCESS)
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_PERMIT, wNewContactId);
- else
- ppro->FreeServerID(wNewContactId, SSIT_ITEM);
- break;
-
- case ACTION_ADDINVISIBLE:
- if (ack->result == ACKRESULT_SUCCESS)
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_DENY, wNewContactId);
- else
- ppro->FreeServerID(wNewContactId, SSIT_ITEM);
- break;
-
- case ACTION_REMOVEVISIBLE:
- if (ack->result == ACKRESULT_SUCCESS) {
- ppro->FreeServerID(wNewContactId, SSIT_ITEM);
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_PERMIT, 0);
- }
- break;
-
- case ACTION_REMOVEINVISIBLE:
- if (ack->result == ACKRESULT_SUCCESS) {
- ppro->FreeServerID(wNewContactId, SSIT_ITEM);
- ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_DENY, 0);
- }
- break;
- }
-
- // Update the log window
- GetLastUploadLogLine(hwndDlg, szLastLogLine, MAX_PATH);
- DeleteLastUploadLogLine(hwndDlg);
- AppendToUploadLog(hwndDlg, "%s%s", szLastLogLine,
- ICQTranslateUtfStatic(getServerResultDesc(ack->lParam), str, MAX_PATH));
-
- if (!bMulti)
- SetTimer(hwndDlg, M_UPLOADMORE, dwUploadDelay, nullptr); // delay
- }
- break;
-
- case WM_TIMER:
- switch (wParam) {
- case M_UPLOADMORE:
- KillTimer(hwndDlg, M_UPLOADMORE);
- if (currentAction == ACTION_MOVECONTACT)
- dwUploadDelay /= 2; // turn it back
-
- PostMessage(hwndDlg, M_UPLOADMORE, 0, 0);
- return 0;
- }
-
- // The M_UPLOADMORE window message is received when the user presses 'Update'
- // and every time an ack from the server has been taken care of.
- case M_UPLOADMORE:
- {
- char str[MAX_PATH];
-
- switch (currentState) {
- case STATE_REGROUP:
- // TODO: iterate over all checked groups and create if needed
- // if creation requires reallocation of groups do it here
- currentState = STATE_ITEMS;
- hCurrentContact = NULL;
- PostMessage(hwndDlg, M_UPLOADMORE, 0, 0);
- break;
-
- case STATE_ITEMS:
- // Iterate over all contacts until one is found that
- // needs to be updated on the server
- MCONTACT hContact;
- if (hCurrentContact == NULL)
- hContact = db_find_first(ppro->m_szModuleName);
- else { // we do not want to go thru all contacts over and over again
- hContact = hCurrentContact;
- if (lastAckResult) // if the last operation on this contact fail, do not do it again, go to next
- hContact = db_find_next(hContact, ppro->m_szModuleName);
- }
-
- while (hContact) {
- hCurrentContact = hContact;
-
- HWND hwndList = GetDlgItem(hwndDlg, IDC_CLIST);
- HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, hContact, 0);
- if (hItem) {
- int isChecked = SendMessage(hwndList, CLM_GETCHECKMARK, (WPARAM)hItem, 0) != 0;
- int isOnServer = ppro->getWord(hContact, DBSETTING_SERVLIST_ID, 0) != 0;
-
- DWORD dwUin;
- uid_str szUid;
- BOOL bUidOk = !ppro->getContactUid(hContact, &dwUin, &szUid);
-
- // Is this one out of sync?
- if (bUidOk && (isChecked != isOnServer)) {
- // Only upload custom nicks
- char *pszNick = ppro->getSettingStringUtf(hContact, "CList", "MyHandle", nullptr);
-
- if (isChecked) { // Queue for uploading
- char *pszGroup = ppro->getContactCListGroup(hContact);
- if (!mir_strlen(pszGroup))
- pszGroup = null_strdup(DEFAULT_SS_GROUP);
-
- // Get group ID from cache, if not ready use parent group, if still not ready create one
- wNewGroupId = ppro->getServListGroupLinkID(pszGroup);
- if (!wNewGroupId && strstrnull(pszGroup, "\\") != nullptr) { // if it is sub-group, take master parent
- strstrnull(pszGroup, "\\")[0] = '\0';
- wNewGroupId = ppro->getServListGroupLinkID(pszGroup);
- }
- if (!wNewGroupId && currentAction != ACTION_ADDGROUP) { // if the group still does not exist and there was no try before, try to add group
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Adding group \"%s\"..."), str, MAX_PATH), pszGroup);
-
- wNewGroupId = ppro->GenerateServerID(SSIT_GROUP, 0); // ???
- szNewGroupName = pszGroup;
- currentAction = ACTION_ADDGROUP;
- currentSequence = sendUploadGroup(ppro, ICQ_LISTS_ADDTOLIST, wNewGroupId, pszGroup);
- SAFE_FREE(&pszNick);
- return FALSE;
- }
-
- SAFE_FREE(&pszGroup);
-
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Uploading %s..."), str, MAX_PATH), pszNick ? pszNick : strUID(dwUin, szUid));
-
- currentAction = ACTION_ADDBUDDY;
-
- if (wNewGroupId) {
- wNewContactId = ppro->GenerateServerID(SSIT_ITEM, 0);
-
- currentSequence = sendUploadBuddy(ppro, hCurrentContact, ICQ_LISTS_ADDTOLIST, dwUin, szUid,
- wNewContactId, wNewGroupId, SSI_ITEM_BUDDY);
- SAFE_FREE(&pszNick);
- return FALSE;
- }
-
- char szLastLogLine[MAX_PATH];
- // Update the log window with the failure and continue with next contact
- GetLastUploadLogLine(hwndDlg, szLastLogLine, MAX_PATH);
- DeleteLastUploadLogLine(hwndDlg);
- AppendToUploadLog(hwndDlg, "%s%s", szLastLogLine, ICQTranslateUtfStatic(LPGEN("FAILED"), str, MAX_PATH));
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("No upload group available"), str, MAX_PATH));
- ppro->debugLogA("Upload failed, no group");
- currentState = STATE_READY;
- }
- else { // Queue for deletion
- if (pszNick)
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting %s..."), str, MAX_PATH), pszNick);
- else
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting %s..."), str, MAX_PATH), strUID(dwUin, szUid));
-
- wNewGroupId = ppro->getWord(hContact, DBSETTING_SERVLIST_GROUP, 0);
- wNewContactId = ppro->getWord(hContact, DBSETTING_SERVLIST_ID, 0);
- currentAction = ACTION_REMOVEBUDDY;
- currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_REMOVEFROMLIST, dwUin, szUid,
- wNewContactId, wNewGroupId, SSI_ITEM_BUDDY);
- }
- SAFE_FREE((void**)&pszNick);
- break;
- }
-
- // the contact is and should be on server, check if it is in correct group, move otherwise
- if (bUidOk && isChecked) {
- WORD wCurrentGroupId = ppro->getWord(hContact, DBSETTING_SERVLIST_GROUP, 0);
-
- char *pszGroup = ppro->getContactCListGroup(hContact);
- if (!mir_strlen(pszGroup))
- pszGroup = null_strdup(DEFAULT_SS_GROUP);
-
- wNewGroupId = ppro->getServListGroupLinkID(pszGroup);
- if (!wNewGroupId && strstrnull(pszGroup, "\\") != nullptr) { // if it is sub-group, take master parent
- strstrnull(pszGroup, "\\")[0] = '\0';
- wNewGroupId = ppro->getServListGroupLinkID(pszGroup);
- }
-
- // if the group still does not exist and there was no try before, try to add group
- if (!wNewGroupId && currentAction != ACTION_ADDGROUP) {
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Adding group \"%s\"..."), str, MAX_PATH), pszGroup);
-
- wNewGroupId = ppro->GenerateServerID(SSIT_GROUP, 0);
- szNewGroupName = pszGroup;
- currentAction = ACTION_ADDGROUP;
- currentSequence = sendUploadGroup(ppro, ICQ_LISTS_ADDTOLIST, wNewGroupId, pszGroup);
- return FALSE;
- }
-
- // we have a group the contact should be in, move it
- if (wNewGroupId && (wNewGroupId != wCurrentGroupId)) {
- WORD wCurrentContactId = ppro->getWord(hContact, DBSETTING_SERVLIST_ID, 0);
-
- char *pszNick = ppro->getSettingStringUtf(hContact, "CList", "MyHandle", nullptr);
- if (pszNick)
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Moving %s to group \"%s\"..."), str, MAX_PATH), pszNick, pszGroup);
- else
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Moving %s to group \"%s\"..."), str, MAX_PATH), strUID(dwUin, szUid), pszGroup);
-
- currentAction = ACTION_MOVECONTACT;
- wNewContactId = ppro->GenerateServerID(SSIT_ITEM, 0);
- sendUploadBuddy(ppro, hContact, ICQ_LISTS_REMOVEFROMLIST, dwUin, szUid, wCurrentContactId, wCurrentGroupId, SSI_ITEM_BUDDY);
- currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_ADDTOLIST, dwUin, szUid, wNewContactId, wNewGroupId, SSI_ITEM_BUDDY);
- SAFE_FREE((void**)&pszNick);
- SAFE_FREE((void**)&pszGroup);
-
- break;
- }
- SAFE_FREE((void**)&pszGroup);
- }
- }
- hContact = db_find_next(hContact);
- }
- if (!hContact) {
- currentState = STATE_VISIBILITY;
- hCurrentContact = NULL;
- PostMessage(hwndDlg, M_UPLOADMORE, 0, 0);
- }
- break;
-
- case STATE_VISIBILITY:
- // Iterate over all contacts until one is found that
- // needs to be updated on the server
- if (hCurrentContact == NULL)
- hContact = db_find_first(ppro->m_szModuleName);
- else { // we do not want to go thru all contacts over and over again
- hContact = hCurrentContact;
- if (lastAckResult) // if the last operation on this contact fail, do not do it again, go to next
- hContact = db_find_next(hContact, ppro->m_szModuleName);
- }
-
- while (hContact) {
- WORD wApparentMode = ppro->getWord(hContact, "ApparentMode", 0);
- WORD wDenyId = ppro->getWord(hContact, DBSETTING_SERVLIST_DENY, 0);
- WORD wPermitId = ppro->getWord(hContact, DBSETTING_SERVLIST_PERMIT, 0);
- WORD wIgnoreId = ppro->getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0);
-
- hCurrentContact = hContact;
-
- DWORD dwUin;
- uid_str szUid;
- ppro->getContactUid(hContact, &dwUin, &szUid);
-
- if (wApparentMode == ID_STATUS_ONLINE) { // contact is on the visible list
- if (wPermitId == 0) {
- currentAction = ACTION_ADDVISIBLE;
- wNewContactId = ppro->GenerateServerID(SSIT_ITEM, 0);
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Adding %s to visible list..."), str, MAX_PATH), strUID(dwUin, szUid));
- currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_ADDTOLIST, dwUin, szUid, wNewContactId, 0, SSI_ITEM_PERMIT);
- break;
- }
- }
- if (wApparentMode == ID_STATUS_OFFLINE) { // contact is on the invisible list
- if (wDenyId == 0 && wIgnoreId == 0) {
- currentAction = ACTION_ADDINVISIBLE;
- wNewContactId = ppro->GenerateServerID(SSIT_ITEM, 0);
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Adding %s to invisible list..."), str, MAX_PATH), strUID(dwUin, szUid));
- currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_ADDTOLIST, dwUin, szUid, wNewContactId, 0, SSI_ITEM_DENY);
- break;
- }
- }
- if (wApparentMode != ID_STATUS_ONLINE) { // contact is not on visible list
- if (wPermitId != 0) {
- currentAction = ACTION_REMOVEVISIBLE;
- wNewContactId = wPermitId;
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting %s from visible list..."), str, MAX_PATH), strUID(dwUin, szUid));
- currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_REMOVEFROMLIST, dwUin, szUid, wNewContactId, 0, SSI_ITEM_PERMIT);
- break;
- }
- }
- if (wApparentMode != ID_STATUS_OFFLINE) { // contact is not on invisible list
- if (wDenyId != 0) {
- currentAction = ACTION_REMOVEINVISIBLE;
- wNewContactId = wDenyId;
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting %s from invisible list..."), str, MAX_PATH), strUID(dwUin, szUid));
- currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_REMOVEFROMLIST, dwUin, szUid, wNewContactId, 0, SSI_ITEM_DENY);
- break;
- }
- }
- hContact = db_find_next(hContact);
- }
- if (!hContact) {
- currentState = STATE_CONSOLIDATE;
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Cleaning groups"), str, MAX_PATH));
- EnableDlgItem(hwndDlg, IDCANCEL, FALSE);
- enumServerGroups(ppro);
- PostMessage(hwndDlg, M_UPLOADMORE, 0, 0);
- }
- break;
-
- case STATE_CONSOLIDATE: // updage group data, remove redundant groups
- if (currentAction == ACTION_UPDATESTATE)
- DeleteLastUploadLogLine(hwndDlg);
-
- if (cbGroupIds) { // some groups in the list
- void* groupData;
- int groupSize;
-
- cbGroupIds--;
- wNewGroupId = pwGroupIds[cbGroupIds];
-
- if (groupData = ppro->collectBuddyGroup(wNewGroupId, &groupSize)) { // the group is still not empty, just update it
- char *pszGroup = ppro->getServListGroupName(wNewGroupId);
- cookie_servlist_action* ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
-
- ack->dwAction = SSA_SERVLIST_ACK;
- ack->wGroupId = wNewGroupId;
- currentSequence = ppro->AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack);
- ack->lParam = currentSequence;
- currentAction = ACTION_UPDATESTATE;
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Updating group \"%s\"..."), str, MAX_PATH), pszGroup);
-
- ppro->icq_sendServerGroup(currentSequence, ICQ_LISTS_UPDATEGROUP, wNewGroupId, pszGroup, groupData, groupSize, 0);
-
- SAFE_FREE((void**)&pszGroup);
- }
- else { // the group is empty, delete it if it does not have sub-groups
- if (!ppro->CheckServerID((WORD)(wNewGroupId + 1), 0) || ppro->getServListGroupLevel((WORD)(wNewGroupId + 1)) == 0) { // is next id an sub-group, if yes, we cannot delete this group
- char *pszGroup = ppro->getServListGroupName(wNewGroupId);
- currentAction = ACTION_REMOVEGROUP;
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting group \"%s\"..."), str, MAX_PATH), pszGroup);
- currentSequence = sendUploadGroup(ppro, ICQ_LISTS_REMOVEFROMLIST, wNewGroupId, pszGroup);
- SAFE_FREE((void**)&pszGroup);
- }
- else { // update empty group
- char *pszGroup = ppro->getServListGroupName(wNewGroupId);
- cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action));
-
- ack->dwAction = SSA_SERVLIST_ACK;
- ack->wGroupId = wNewGroupId;
- currentSequence = ppro->AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack);
- ack->lParam = currentSequence;
- currentAction = ACTION_UPDATESTATE;
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Updating group \"%s\"..."), str, MAX_PATH), pszGroup);
-
- ppro->icq_sendServerGroup(currentSequence, ICQ_LISTS_UPDATEGROUP, wNewGroupId, pszGroup, nullptr, 0, 0);
-
- SAFE_FREE((void**)&pszGroup);
- }
- }
- SAFE_FREE((void**)&groupData); // free the memory
- }
- else { // all groups processed
- SAFE_FREE((void**)&pwGroupIds);
- currentState = STATE_READY;
- }
- break;
- }
-
- if (currentState == STATE_READY) {
- // All contacts are in sync
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("All operations complete"), str, MAX_PATH));
- EnableDlgItem(hwndDlg, IDCANCEL, TRUE);
- SetDlgItemText(hwndDlg, IDCANCEL, TranslateT("Close"));
-
- // end server modifications here
- ppro->servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100);
- working = 0;
- UpdateCheckmarks(GetDlgItem(hwndDlg, IDC_CLIST), ppro, hItemAll);
- if (hProtoAckHook)
- UnhookEvent(hProtoAckHook);
- }
- }
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDOK:
- SendDlgItemMessage(hwndDlg, IDC_LOG, LB_RESETCONTENT, 0, 0);
- if (!ppro->icqOnline()) {
- char str[MAX_PATH];
- AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("You have to be online to synchronize the server-list!"), str, MAX_PATH));
- break;
- }
- working = 1;
- hCurrentContact = NULL;
- currentState = STATE_REGROUP;
- currentAction = ACTION_NONE;
- icq_ShowMultipleControls(hwndDlg, settingsControls, _countof(settingsControls), SW_HIDE);
- EnableDlgItem(hwndDlg, IDC_CLIST, FALSE);
- hProtoAckHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, M_PROTOACK);
-
- // start server modifications here
- ppro->servlistPostPacket(nullptr, 0, SSO_BEGIN_OPERATION | SSOF_IMPORT_OPERATION, 100);
- PostMessage(hwndDlg, M_UPLOADMORE, 0, 0);
- break;
-
- case IDCANCEL: // TODO: this must be clean
- DestroyWindow(hwndDlg);
- break;
- }
- break;
-
- case WM_NOTIFY:
- if (((NMHDR*)lParam)->idFrom == IDC_CLIST) {
- HWND hClist = GetDlgItem(hwndDlg, IDC_CLIST);
-
- switch (((NMHDR*)lParam)->code) {
- case CLN_OPTIONSCHANGED:
- ResetCListOptions(hClist);
- break;
-
- case CLN_NEWCONTACT:
- case CLN_CONTACTMOVED:
- // Delete non-icq contacts
- DeleteOtherContactsFromControl(hClist, ppro);
- if (hItemAll)
- UpdateAllContactsCheckmark(hClist, ppro, hItemAll);
- break;
-
- case CLN_LISTREBUILT:
- {
- int bCheck = false;
-
- // Delete non-icq contacts
- if (ppro) {
- DeleteOtherContactsFromControl(hClist, ppro);
- if (!bListInit) // do not enter twice
- bCheck = UpdateCheckmarks(hClist, ppro, nullptr);
- }
-
- if (!hItemAll) { // Add the "All contacts" item
- CLCINFOITEM cii = { 0 };
- cii.cbSize = sizeof(cii);
- cii.flags = CLCIIF_GROUPFONT | CLCIIF_CHECKBOX;
- cii.pszText = TranslateT("** All contacts **");
- hItemAll = (HANDLE)SendMessage(hClist, CLM_ADDINFOITEM, 0, (LPARAM)&cii);
- }
-
- SendMessage(hClist, CLM_SETCHECKMARK, (WPARAM)hItemAll, bCheck);
- }
- break;
-
- case CLN_CHECKCHANGED:
- if (!bListInit) {
- NMCLISTCONTROL *nm = (NMCLISTCONTROL*)lParam;
- if (nm->flags&CLNF_ISINFO) {
- int check = SendMessage(hClist, CLM_GETCHECKMARK, (WPARAM)hItemAll, 0);
-
- for (auto &hContact : ppro->AccContacts()) {
- HANDLE hItem = (HANDLE)SendMessage(hClist, CLM_FINDCONTACT, hContact, 0);
- if (hItem)
- SendMessage(hClist, CLM_SETCHECKMARK, (WPARAM)hItem, check);
- }
- }
- else UpdateAllContactsCheckmark(hClist, ppro, hItemAll);
- }
- break;
- }
- }
- break;
-
- case WM_CLOSE:
- DestroyWindow(hwndDlg);
- break;
-
- case WM_DESTROY:
- if (hProtoAckHook)
- UnhookEvent(hProtoAckHook);
- if (working) // end server modifications here
- ppro->servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100);
-
- hwndUploadContacts = nullptr;
- working = 0;
- break;
- }
-
- return FALSE;
-}
-
-void CIcqProto::ShowUploadContactsDialog(void)
-{
- if (hwndUploadContacts == nullptr) {
- hItemAll = nullptr;
- hwndUploadContacts = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_ICQUPLOADLIST), nullptr, DlgProcUploadList, LPARAM(this));
- }
-
- SetForegroundWindow(hwndUploadContacts);
-}
diff --git a/protocols/IcqOscarJ/src/icq_xstatus.cpp b/protocols/IcqOscarJ/src/icq_xstatus.cpp
deleted file mode 100644
index 365d39b586..0000000000
--- a/protocols/IcqOscarJ/src/icq_xstatus.cpp
+++ /dev/null
@@ -1,1133 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Angeli-Ka, Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Support for Custom Statuses
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-#include "m_extraicons.h"
-#include "../icq_xstatus/src/resource.h"
-
-static HANDLE hXStatusIcons[XSTATUS_COUNT];
-static int hXStatusCListIcons[XSTATUS_COUNT];
-static BOOL bXStatusCListIconsValid[XSTATUS_COUNT];
-
-int OnReloadIcons(WPARAM, LPARAM)
-{
- memset(bXStatusCListIconsValid, 0, sizeof(bXStatusCListIconsValid));
- return 0;
-}
-
-BYTE CIcqProto::getContactXStatus(MCONTACT hContact)
-{
- if (!m_bXStatusEnabled && !m_bMoodsEnabled)
- return 0;
-
- BYTE bXStatus = getByte(hContact, DBSETTING_XSTATUS_ID, 0);
- return (bXStatus < 1 || bXStatus > XSTATUS_COUNT) ? 0 : bXStatus;
-}
-
-DWORD CIcqProto::sendXStatusDetailsRequest(MCONTACT hContact, int bForced)
-{
- DWORD dwCookie = 0;
-
- // only request custom status detail when the contact has one
- if (m_bXStatusEnabled && getContactXStatus(hContact) != 0) {
- int nNotifyLen = 94 + UINMAXLEN;
- char *szNotify = (char*)_alloca(nNotifyLen);
-
- mir_snprintf(szNotify, nNotifyLen, "<srv><id>cAwaySrv</id><req><id>AwayStat</id><trans>1</trans><senderId>%d</senderId></req></srv>", m_dwLocalUIN);
-
- dwCookie = SendXtrazNotifyRequest(hContact, "<Q><PluginID>srvMng</PluginID></Q>", szNotify, bForced);
- }
- return dwCookie;
-}
-
-DWORD CIcqProto::requestXStatusDetails(MCONTACT hContact, BOOL bAllowDelay)
-{
- if (!validateStatusMessageRequest(hContact, MTYPE_SCRIPT_NOTIFY))
- return 0; // apply privacy rules
-
- if (!CheckContactCapabilities(hContact, CAPF_XSTATUS))
- return 0; // contact does not have xstatus
-
- // delay is disabled only if fired from dialog
- if (!CheckContactCapabilities(hContact, CAPF_XTRAZ) && bAllowDelay)
- return 0; // Contact does not support xtraz, do not request details
-
- struct rates_xstatus_request : public rates_queue_item
- {
- protected:
- virtual rates_queue_item* copyItem(rates_queue_item *aDest = nullptr)
- {
- rates_xstatus_request *pDest = (rates_xstatus_request*)aDest;
- if (!pDest)
- pDest = new rates_xstatus_request(ppro, wGroup);
-
- pDest->bForced = bForced;
- return rates_queue_item::copyItem(pDest);
- };
- public:
- rates_xstatus_request(CIcqProto *ppro, WORD wGroup) : rates_queue_item(ppro, wGroup) {};
- virtual ~rates_xstatus_request() {};
-
- virtual void execute()
- {
- dwCookie = ppro->sendXStatusDetailsRequest(hContact, bForced);
- };
-
- BOOL bForced;
- DWORD dwCookie;
- };
-
- WORD wGroup;
- {
- mir_cslock l(m_ratesMutex);
- wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND);
- }
-
- rates_xstatus_request rr(this, wGroup);
- rr.bForced = !bAllowDelay;
- rr.hContact = hContact;
-
- // delay at least one sec if allowed
- if (!handleRateItem(&rr, RQT_REQUEST, 1000, bAllowDelay))
- return rr.dwCookie;
-
- return -1; // delayed
-}
-
-static HANDLE LoadXStatusIconLibrary(wchar_t *path, const wchar_t *sub)
-{
- wchar_t* p = wcsrchr(path, '\\');
- HANDLE hLib;
-
- mir_wstrcpy(p, sub);
- mir_wstrcat(p, L"\\xstatus_ICQ.dll");
- if (hLib = LoadLibrary(path))
- return hLib;
- mir_wstrcpy(p, sub);
- mir_wstrcat(p, L"\\xstatus_icons.dll");
- if (hLib = LoadLibrary(path))
- return hLib;
- mir_wstrcpy(p, L"\\");
- return hLib;
-}
-
-static wchar_t* InitXStatusIconLibrary(wchar_t *buf, size_t buf_size)
-{
- wchar_t path[2 * MAX_PATH];
- HMODULE hXStatusIconsDLL;
-
- // get miranda's exe path
- GetModuleFileName(nullptr, path, MAX_PATH);
-
- hXStatusIconsDLL = (HMODULE)LoadXStatusIconLibrary(path, L"\\Icons");
- if (!hXStatusIconsDLL) // TODO: add "Custom Folders" support
- hXStatusIconsDLL = (HMODULE)LoadXStatusIconLibrary(path, L"\\Plugins");
-
- if (hXStatusIconsDLL) {
- null_strcpy(buf, path, buf_size - 1);
-
- char ident[MAX_PATH];
- if (LoadStringA(hXStatusIconsDLL, IDS_IDENTIFY, ident, sizeof(ident)) == 0 || mir_strcmp(ident, "# Custom Status Icons #"))
- *buf = 0;
-
- FreeLibrary(hXStatusIconsDLL);
- }
- else *buf = 0;
-
- return buf;
-}
-
-HICON CIcqProto::getXStatusIcon(int bStatus, UINT flags)
-{
- HICON icon = nullptr;
-
- if (bStatus > 0 && bStatus <= XSTATUS_COUNT)
- icon = IcoLib_GetIconByHandle(hXStatusIcons[bStatus - 1], (flags & LR_BIGICON) != 0);
-
- return (flags & LR_SHARED || !icon) ? icon : CopyIcon(icon);
-}
-
-void setContactExtraIcon(MCONTACT hContact, int xstatus)
-{
- ExtraIcon_SetIcon(hExtraXStatus, hContact, (xstatus > 0) ? hXStatusIcons[xstatus - 1] : nullptr);
-}
-
-#define NULLCAP {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-
-capstr capXStatus[XSTATUS_COUNT] = {
- {0x01, 0xD8, 0xD7, 0xEE, 0xAC, 0x3B, 0x49, 0x2A, 0xA5, 0x8D, 0xD3, 0xD8, 0x77, 0xE6, 0x6B, 0x92},
- {0x5A, 0x58, 0x1E, 0xA1, 0xE5, 0x80, 0x43, 0x0C, 0xA0, 0x6F, 0x61, 0x22, 0x98, 0xB7, 0xE4, 0xC7},
- {0x83, 0xC9, 0xB7, 0x8E, 0x77, 0xE7, 0x43, 0x78, 0xB2, 0xC5, 0xFB, 0x6C, 0xFC, 0xC3, 0x5B, 0xEC},
- {0xE6, 0x01, 0xE4, 0x1C, 0x33, 0x73, 0x4B, 0xD1, 0xBC, 0x06, 0x81, 0x1D, 0x6C, 0x32, 0x3D, 0x81},
- {0x8C, 0x50, 0xDB, 0xAE, 0x81, 0xED, 0x47, 0x86, 0xAC, 0xCA, 0x16, 0xCC, 0x32, 0x13, 0xC7, 0xB7},
- {0x3F, 0xB0, 0xBD, 0x36, 0xAF, 0x3B, 0x4A, 0x60, 0x9E, 0xEF, 0xCF, 0x19, 0x0F, 0x6A, 0x5A, 0x7F},
- {0xF8, 0xE8, 0xD7, 0xB2, 0x82, 0xC4, 0x41, 0x42, 0x90, 0xF8, 0x10, 0xC6, 0xCE, 0x0A, 0x89, 0xA6},
- {0x80, 0x53, 0x7D, 0xE2, 0xA4, 0x67, 0x4A, 0x76, 0xB3, 0x54, 0x6D, 0xFD, 0x07, 0x5F, 0x5E, 0xC6},
- {0xF1, 0x8A, 0xB5, 0x2E, 0xDC, 0x57, 0x49, 0x1D, 0x99, 0xDC, 0x64, 0x44, 0x50, 0x24, 0x57, 0xAF},
- {0x1B, 0x78, 0xAE, 0x31, 0xFA, 0x0B, 0x4D, 0x38, 0x93, 0xD1, 0x99, 0x7E, 0xEE, 0xAF, 0xB2, 0x18},
- {0x61, 0xBE, 0xE0, 0xDD, 0x8B, 0xDD, 0x47, 0x5D, 0x8D, 0xEE, 0x5F, 0x4B, 0xAA, 0xCF, 0x19, 0xA7},
- {0x48, 0x8E, 0x14, 0x89, 0x8A, 0xCA, 0x4A, 0x08, 0x82, 0xAA, 0x77, 0xCE, 0x7A, 0x16, 0x52, 0x08},
- {0x10, 0x7A, 0x9A, 0x18, 0x12, 0x32, 0x4D, 0xA4, 0xB6, 0xCD, 0x08, 0x79, 0xDB, 0x78, 0x0F, 0x09},
- {0x6F, 0x49, 0x30, 0x98, 0x4F, 0x7C, 0x4A, 0xFF, 0xA2, 0x76, 0x34, 0xA0, 0x3B, 0xCE, 0xAE, 0xA7},
- {0x12, 0x92, 0xE5, 0x50, 0x1B, 0x64, 0x4F, 0x66, 0xB2, 0x06, 0xB2, 0x9A, 0xF3, 0x78, 0xE4, 0x8D},
- {0xD4, 0xA6, 0x11, 0xD0, 0x8F, 0x01, 0x4E, 0xC0, 0x92, 0x23, 0xC5, 0xB6, 0xBE, 0xC6, 0xCC, 0xF0},
- {0x60, 0x9D, 0x52, 0xF8, 0xA2, 0x9A, 0x49, 0xA6, 0xB2, 0xA0, 0x25, 0x24, 0xC5, 0xE9, 0xD2, 0x60},
- {0x63, 0x62, 0x73, 0x37, 0xA0, 0x3F, 0x49, 0xFF, 0x80, 0xE5, 0xF7, 0x09, 0xCD, 0xE0, 0xA4, 0xEE},
- {0x1F, 0x7A, 0x40, 0x71, 0xBF, 0x3B, 0x4E, 0x60, 0xBC, 0x32, 0x4C, 0x57, 0x87, 0xB0, 0x4C, 0xF1},
- {0x78, 0x5E, 0x8C, 0x48, 0x40, 0xD3, 0x4C, 0x65, 0x88, 0x6F, 0x04, 0xCF, 0x3F, 0x3F, 0x43, 0xDF},
- {0xA6, 0xED, 0x55, 0x7E, 0x6B, 0xF7, 0x44, 0xD4, 0xA5, 0xD4, 0xD2, 0xE7, 0xD9, 0x5C, 0xE8, 0x1F},
- {0x12, 0xD0, 0x7E, 0x3E, 0xF8, 0x85, 0x48, 0x9E, 0x8E, 0x97, 0xA7, 0x2A, 0x65, 0x51, 0xE5, 0x8D},
- {0xBA, 0x74, 0xDB, 0x3E, 0x9E, 0x24, 0x43, 0x4B, 0x87, 0xB6, 0x2F, 0x6B, 0x8D, 0xFE, 0xE5, 0x0F},
- {0x63, 0x4F, 0x6B, 0xD8, 0xAD, 0xD2, 0x4A, 0xA1, 0xAA, 0xB9, 0x11, 0x5B, 0xC2, 0x6D, 0x05, 0xA1},
- {0x2C, 0xE0, 0xE4, 0xE5, 0x7C, 0x64, 0x43, 0x70, 0x9C, 0x3A, 0x7A, 0x1C, 0xE8, 0x78, 0xA7, 0xDC},
- {0x10, 0x11, 0x17, 0xC9, 0xA3, 0xB0, 0x40, 0xF9, 0x81, 0xAC, 0x49, 0xE1, 0x59, 0xFB, 0xD5, 0xD4},
- {0x16, 0x0C, 0x60, 0xBB, 0xDD, 0x44, 0x43, 0xF3, 0x91, 0x40, 0x05, 0x0F, 0x00, 0xE6, 0xC0, 0x09},
- {0x64, 0x43, 0xC6, 0xAF, 0x22, 0x60, 0x45, 0x17, 0xB5, 0x8C, 0xD7, 0xDF, 0x8E, 0x29, 0x03, 0x52},
- {0x16, 0xF5, 0xB7, 0x6F, 0xA9, 0xD2, 0x40, 0x35, 0x8C, 0xC5, 0xC0, 0x84, 0x70, 0x3C, 0x98, 0xFA},
- {0x63, 0x14, 0x36, 0xff, 0x3f, 0x8a, 0x40, 0xd0, 0xa5, 0xcb, 0x7b, 0x66, 0xe0, 0x51, 0xb3, 0x64},
- {0xb7, 0x08, 0x67, 0xf5, 0x38, 0x25, 0x43, 0x27, 0xa1, 0xff, 0xcf, 0x4c, 0xc1, 0x93, 0x97, 0x97},
- {0xdd, 0xcf, 0x0e, 0xa9, 0x71, 0x95, 0x40, 0x48, 0xa9, 0xc6, 0x41, 0x32, 0x06, 0xd6, 0xf2, 0x80},
- NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP,
- NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP,
- NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP,
- NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP,
- NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP,
- NULLCAP, NULLCAP, NULLCAP, NULLCAP };
-
-const char *nameXStatus[XSTATUS_COUNT] = {
- LPGEN("Angry"), // 23
- LPGEN("Taking a bath"), // 1
- LPGEN("Tired"), // 2
- LPGEN("Birthday"), // 3
- LPGEN("Drinking beer"), // 4
- LPGEN("Thinking"), // 5
- LPGEN("Eating"), // 80
- LPGEN("Watching TV"), // 7
- LPGEN("Meeting"), // 8
- LPGEN("Coffee"), // 9
- LPGEN("Listening to music"),// 10
- LPGEN("Business"), // 11
- LPGEN("Shooting"), // 12
- LPGEN("Having fun"), // 13
- LPGEN("On the phone"), // 14
- LPGEN("Gaming"), // 15
- LPGEN("Studying"), // 16
- LPGEN("Shopping"), // 0
- LPGEN("Feeling sick"), // 17
- LPGEN("Sleeping"), // 18
- LPGEN("Surfing"), // 19
- LPGEN("Internet"), // 20
- LPGEN("Working"), // 21
- LPGEN("Typing"), // 22
- LPGEN("Picnic"), // 66
- LPGEN("Cooking"),
- LPGEN("Smoking"),
- LPGEN("I'm high"),
- LPGEN("On WC"), // 68
- LPGEN("To be or not to be"),// 77
- LPGEN("Watching pro7 on TV"),
- LPGEN("Love"), // 61
- LPGEN("Hot Dog"), //6
- LPGEN("Rough"), //24
- LPGEN("Rock On"), //25
- LPGEN("Baby"), //26
- LPGEN("Soccer"), //27
- LPGEN("Pirate"), //28
- LPGEN("Cyclop"), //29
- LPGEN("Monkey"), //30
- LPGEN("Birdie"), //31
- LPGEN("Cool"), //32
- LPGEN("Evil"), //33
- LPGEN("Alien"), //34
- LPGEN("Scooter"), //35
- LPGEN("Mask"), //36
- LPGEN("Money"), //37
- LPGEN("Pilot"), //38
- LPGEN("Afro"), //39
- LPGEN("St. Patrick"), //40
- LPGEN("Headmaster"), //41
- LPGEN("Lips"), //42
- LPGEN("Ice-Cream"), //43
- LPGEN("Pink Lady"), //44
- LPGEN("Up yours"), //45
- LPGEN("Laughing"), //46
- LPGEN("Dog"), //47
- LPGEN("Candy"), //48
- LPGEN("Crazy Professor"),//50
- LPGEN("Ninja"), //51
- LPGEN("Cocktail"), //52
- LPGEN("Punch"), //53
- LPGEN("Donut"), //54
- LPGEN("Feeling Good"), //55
- LPGEN("Lollypop"), //56
- LPGEN("Oink Oink"), //57
- LPGEN("Kitty"), //58
- LPGEN("Sumo"), //59
- LPGEN("Broken hearted"),//60
- LPGEN("Free for chat"), //62
- LPGEN("@home"), //63
- LPGEN("@work"), //64
- LPGEN("Strawberry"), //65
- LPGEN("Angel"), //67
- LPGEN("Pizza"), //69
- LPGEN("Snoring"), //70
- LPGEN("On my mobile"), //71
- LPGEN("Depressed"), //72
- LPGEN("Beetle"), //73
- LPGEN("Double Rainbow"),//74
- LPGEN("Basketball"), //75
- LPGEN("Cupid shot me"), //76
- LPGEN("Celebrating"), //78
- LPGEN("Sushi"), //79
- LPGEN("Playing"), //81
- LPGEN("Writing") //84
-};
-
-const int moodXStatus[XSTATUS_COUNT] = {
- 23,
- 1,
- 2,
- 3,
- 4,
- 5,
- 80,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 0,
- 17,
- 18,
- 19,
- 20,
- 21,
- 22,
- 66,
- -1,
- -1,
- -1,
- 68,
- 77,
- -1,
- 61,
- 6,
- 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,
- 50,
- 51,
- 52,
- 53,
- 54,
- 55,
- 56,
- 57,
- 58,
- 59,
- 60,
- 62,
- 63,
- 64,
- 65,
- 67,
- 69,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 78,
- 79,
- 81,
- 84 };
-
-void CIcqProto::handleXStatusCaps(DWORD dwUIN, char *szUID, MCONTACT hContact, BYTE *caps, int capsize, char *moods, int moodsize)
-{
- int bChanged = FALSE;
- int nCustomStatusID = 0, nMoodID = 0;
-
- if (!m_bXStatusEnabled && !m_bMoodsEnabled) {
- ClearContactCapabilities(hContact, CAPF_STATUS_MOOD | CAPF_XSTATUS);
- return;
- }
- int nOldXStatusID = getContactXStatus(hContact);
-
- if (m_bMoodsEnabled) {
- // process custom statuses (moods) from ICQ6
- if (moods) {
- if (moodsize > 0)
- if (moodsize >= 32)
- moods[32] = '\0';
-
- for (int i = 0; i < XSTATUS_COUNT; i++) {
- char szMoodId[32], szMoodData[32];
-
- null_strcpy(szMoodData, moods, moodsize);
-
- if (moodXStatus[i] == -1) continue;
- mir_snprintf(szMoodId, "0icqmood%d", moodXStatus[i]);
- if (!mir_strcmp(szMoodId, szMoodData)) {
- BYTE bXStatusId = (BYTE)(i + 1);
- char str[MAX_PATH];
-
- SetContactCapabilities(hContact, CAPF_STATUS_MOOD);
-
- // only write default name when it is really needed, i.e. on Custom Status change
- if (nOldXStatusID != bXStatusId) {
- setByte(hContact, DBSETTING_XSTATUS_ID, bXStatusId);
- db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_NAME, ICQTranslateUtfStatic(nameXStatus[i], str, MAX_PATH));
- delSetting(hContact, DBSETTING_XSTATUS_MSG);
-
- debugLogA("%s changed mood to %s.", strUID(dwUIN, szUID), ICQTranslateUtfStatic(nameXStatus[i], str, MAX_PATH));
- bChanged = TRUE;
- }
-
- // cannot retrieve mood details here - need to be processed with new user details
- nMoodID = bXStatusId;
-
- break;
- }
- }
-
- if (nMoodID == 0 && moods)
- ClearContactCapabilities(hContact, CAPF_STATUS_MOOD);
- }
- }
-
- if (m_bXStatusEnabled) {
- // detect custom status capabilities
- if (caps) {
- if (capsize > 0)
- for (int i = 0; i < XSTATUS_COUNT; i++) {
- if (MatchCapability(caps, capsize, (const capstr*)capXStatus[i], BINARY_CAP_SIZE)) {
- BYTE bXStatusId = (BYTE)(i + 1);
- char str[MAX_PATH];
-
- SetContactCapabilities(hContact, CAPF_XSTATUS);
-
- // only write default name when it is really needed, i.e. on Custom Status change
- if (nMoodID == 0 && nOldXStatusID != bXStatusId) {
- setByte(hContact, DBSETTING_XSTATUS_ID, bXStatusId);
- db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_NAME, ICQTranslateUtfStatic(nameXStatus[i], str, MAX_PATH));
- delSetting(hContact, DBSETTING_XSTATUS_MSG);
-
- debugLogA("%s changed custom status to %s.", strUID(dwUIN, szUID), ICQTranslateUtfStatic(nameXStatus[i], str, MAX_PATH));
- bChanged = TRUE;
- }
-
- if (getByte("XStatusAuto", DEFAULT_XSTATUS_AUTO))
- requestXStatusDetails(hContact, TRUE);
-
- nCustomStatusID = bXStatusId;
- break;
- }
- }
-
- if (nCustomStatusID == 0)
- ClearContactCapabilities(hContact, CAPF_XSTATUS);
- }
- }
-
- if (nCustomStatusID != 0 && nMoodID != 0 && nCustomStatusID != nMoodID)
- debugLogA("Warning: Diverse custom statuses detected, using mood status.");
-
- if ((nCustomStatusID == 0 && (caps || !m_bXStatusEnabled)) && (nMoodID == 0 && (moods || !m_bMoodsEnabled))) {
- if (getByte(hContact, DBSETTING_XSTATUS_ID, -1) != -1)
- bChanged = TRUE;
- delSetting(hContact, DBSETTING_XSTATUS_ID);
- delSetting(hContact, DBSETTING_XSTATUS_NAME);
- delSetting(hContact, DBSETTING_XSTATUS_MSG);
- }
-
- if (m_bXStatusEnabled != 10 && m_bMoodsEnabled != 10)
- setContactExtraIcon(hContact, nMoodID ? nMoodID : (moods ? 0 : (nCustomStatusID ? nCustomStatusID : nOldXStatusID)));
-}
-
-
-void CIcqProto::updateServerCustomStatus(int fullUpdate)
-{
- BYTE bXStatus = getContactXStatus(NULL);
-
- // update client capabilities
- if (fullUpdate) {
- if (m_bXStatusEnabled)
- setUserInfo();
-
- char szMoodData[32];
-
- // prepare mood id
- if (m_bMoodsEnabled && bXStatus && moodXStatus[bXStatus - 1] != -1)
- mir_snprintf(szMoodData, "0icqmood%d", moodXStatus[bXStatus - 1]);
- else
- szMoodData[0] = '\0';
-
- SetStatusMood(szMoodData, 1500);
- }
-
- char *szStatusNote = nullptr;
-
- // use custom status message as status note
- if (bXStatus && (m_bXStatusEnabled || m_bMoodsEnabled))
- szStatusNote = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, "");
- // retrieve standard status message (e.g. custom status set to none)
- else {
- char **pszMsg = MirandaStatusToAwayMsg(m_iStatus);
- {
- mir_cslock l(m_modeMsgsMutex);
- if (pszMsg)
- szStatusNote = null_strdup(*pszMsg);
- }
-
- // no default status message, set empty
- if (!szStatusNote)
- szStatusNote = null_strdup("");
- }
-
- if (szStatusNote)
- SetStatusNote(szStatusNote, 1500, FALSE);
-
- SAFE_FREE(&szStatusNote);
-}
-
-static LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case WM_CHAR:
- if (wParam == '\n' && GetKeyState(VK_CONTROL) & 0x8000) {
- PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
- return 0;
- }
- if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-a
- SendMessage(hwnd, EM_SETSEL, 0, -1);
- return 0;
- }
- if (wParam == 23 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w
- SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0);
- return 0;
- }
- if (wParam == 127 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-backspace
- DWORD start, end;
- SendMessage(hwnd, EM_GETSEL, (WPARAM)&end, (LPARAM)(PDWORD)NULL);
- SendMessage(hwnd, WM_KEYDOWN, VK_LEFT, 0);
- SendMessage(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)(PDWORD)NULL);
- WCHAR *text = GetWindowTextUcs(hwnd);
- memmove(text + start, text + end, sizeof(WCHAR) * (mir_wstrlen(text) + 1 - end));
- SetWindowTextUcs(hwnd, text);
- SAFE_FREE(&text);
- SendMessage(hwnd, EM_SETSEL, start, start);
- SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), EN_CHANGE), (LPARAM)hwnd);
- return 0;
- }
- break;
- }
- return mir_callNextSubclass(hwnd, MessageEditSubclassProc, msg, wParam, lParam);
-}
-
-struct SetXStatusData
-{
- CIcqProto* ppro;
- BYTE bAction;
- BYTE bXStatus;
- MCONTACT hContact;
- HANDLE hEvent;
- DWORD iEvent;
- int countdown;
- char* okButtonFormat;
-};
-
-struct InitXStatusData
-{
- CIcqProto* ppro;
- BYTE bAction;
- BYTE bXStatus;
- char* szXStatusName;
- char* szXStatusMsg;
- MCONTACT hContact;
-};
-
-#define HM_PROTOACK (WM_USER+10)
-static INT_PTR CALLBACK SetXStatusDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
- SetXStatusData *dat = (SetXStatusData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- char str[MAX_PATH];
-
- switch (message) {
- case HM_PROTOACK:
- {
- ACKDATA *ack = (ACKDATA*)lParam;
- if (ack->type != ICQACKTYPE_XSTATUS_RESPONSE) break;
- if (ack->hContact != dat->hContact) break;
- if ((UINT_PTR)ack->hProcess != dat->iEvent) break;
-
- ShowDlgItem(hwndDlg, IDC_RETRXSTATUS, SW_HIDE);
- ShowDlgItem(hwndDlg, IDC_XMSG, SW_SHOW);
- ShowDlgItem(hwndDlg, IDC_XTITLE, SW_SHOW);
- SetDlgItemText(hwndDlg, IDOK, TranslateT("Close"));
- UnhookEvent(dat->hEvent); dat->hEvent = nullptr;
- char *szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_XSTATUS_NAME, "");
- SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szText);
- SAFE_FREE(&szText);
- szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_XSTATUS_MSG, "");
- SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szText);
- SAFE_FREE(&szText);
- }
- break;
-
- case WM_INITDIALOG:
- {
- InitXStatusData *init = (InitXStatusData*)lParam;
-
- TranslateDialogDefault(hwndDlg);
- dat = (SetXStatusData*)SAFE_MALLOC(sizeof(SetXStatusData));
- dat->ppro = init->ppro;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
- dat->bAction = init->bAction;
-
- if (!init->bAction) { // set our xStatus
- dat->bXStatus = init->bXStatus;
- SendDlgItemMessage(hwndDlg, IDC_XMSG, EM_LIMITTEXT, 1024, 0);
- mir_subclassWindow(GetDlgItem(hwndDlg, IDC_XMSG), MessageEditSubclassProc);
- SetDlgItemTextUtf(hwndDlg, IDC_XMSG, init->szXStatusMsg);
-
- if (dat->ppro->m_bXStatusEnabled) { // custom status enabled, prepare title edit
- SendDlgItemMessage(hwndDlg, IDC_XTITLE, EM_LIMITTEXT, 256, 0);
- mir_subclassWindow(GetDlgItem(hwndDlg, IDC_XTITLE), MessageEditSubclassProc);
- SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, init->szXStatusName);
- }
- else { // only moods enabled, hide title, resize message edit control
- ShowDlgItem(hwndDlg, IDC_XTITLE_STATIC, SW_HIDE);
- ShowDlgItem(hwndDlg, IDC_XTITLE, SW_HIDE);
- MoveDlgItem(hwndDlg, IDC_XMSG_STATIC, 5, 0, 179, 8);
- MoveDlgItem(hwndDlg, IDC_XMSG, 5, 9, 179, 65);
- }
-
- dat->okButtonFormat = GetDlgItemTextUtf(hwndDlg, IDOK);
- dat->countdown = 5;
- SendMessage(hwndDlg, WM_TIMER, 0, 0);
- SetTimer(hwndDlg, 1, 1000, nullptr);
- }
- else { // retrieve contact's xStatus
- dat->hContact = init->hContact;
- dat->bXStatus = dat->ppro->getContactXStatus(dat->hContact);
- dat->okButtonFormat = nullptr;
- SendDlgItemMessage(hwndDlg, IDC_XTITLE, EM_SETREADONLY, 1, 0);
- SendDlgItemMessage(hwndDlg, IDC_XMSG, EM_SETREADONLY, 1, 0);
-
- if (dat->ppro->CheckContactCapabilities(dat->hContact, CAPF_XSTATUS) && !dat->ppro->getByte("XStatusAuto", DEFAULT_XSTATUS_AUTO)) {
- SetDlgItemText(hwndDlg, IDOK, TranslateT("Cancel"));
- dat->hEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_PROTOACK);
- ShowDlgItem(hwndDlg, IDC_RETRXSTATUS, SW_SHOW);
- ShowDlgItem(hwndDlg, IDC_XMSG, SW_HIDE);
- ShowDlgItem(hwndDlg, IDC_XTITLE, SW_HIDE);
- dat->iEvent = dat->ppro->requestXStatusDetails(dat->hContact, FALSE);
- }
- else {
- SetDlgItemText(hwndDlg, IDOK, TranslateT("Close"));
- dat->hEvent = nullptr;
- char *szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_XSTATUS_NAME, "");
- SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szText);
- SAFE_FREE(&szText);
-
- // only for clients supporting just moods and not custom status
- if (dat->ppro->CheckContactCapabilities(dat->hContact, CAPF_STATUS_MOOD) && !dat->ppro->CheckContactCapabilities(dat->hContact, CAPF_XSTATUS)) {
- szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_STATUS_NOTE, "");
- // hide title, resize message edit control
- ShowDlgItem(hwndDlg, IDC_XTITLE_STATIC, SW_HIDE);
- ShowDlgItem(hwndDlg, IDC_XTITLE, SW_HIDE);
- MoveDlgItem(hwndDlg, IDC_XMSG_STATIC, 5, 0, 179, 8);
- MoveDlgItem(hwndDlg, IDC_XMSG, 5, 9, 179, 65);
- }
- else szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_XSTATUS_MSG, "");
-
- SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szText);
- SAFE_FREE(&szText);
- }
- }
-
- if (dat->bXStatus) {
- SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)dat->ppro->getXStatusIcon(dat->bXStatus, LR_SHARED | LR_BIGICON));
- SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)dat->ppro->getXStatusIcon(dat->bXStatus, LR_SHARED));
- }
-
- char buf[MAX_PATH];
- char *format = GetWindowTextUtf(hwndDlg);
-
- mir_snprintf(str, format, dat->bXStatus ? ICQTranslateUtfStatic(nameXStatus[dat->bXStatus - 1], buf, MAX_PATH) : "");
- SetWindowTextUtf(hwndDlg, str);
- SAFE_FREE(&format);
- }
- return TRUE;
-
- case WM_TIMER:
- if (dat->countdown == -1) {
- DestroyWindow(hwndDlg);
- break;
- }
-
- mir_snprintf(str, dat->okButtonFormat, dat->countdown);
- SetDlgItemTextUtf(hwndDlg, IDOK, str);
- dat->countdown--;
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDOK:
- DestroyWindow(hwndDlg);
- break;
-
- case IDC_XTITLE:
- case IDC_XMSG:
- if (!dat->bAction) { // set our xStatus
- KillTimer(hwndDlg, 1);
- SetDlgItemText(hwndDlg, IDOK, TranslateT("OK"));
- }
- }
- break;
-
- case WM_DESTROY:
- if (!dat->bAction) { // set our xStatus
- char szSetting[64];
-
- dat->ppro->setByte(DBSETTING_XSTATUS_ID, dat->bXStatus);
- char *szValue = GetDlgItemTextUtf(hwndDlg, IDC_XMSG);
- mir_snprintf(szSetting, "XStatus%dMsg", dat->bXStatus);
- db_set_utf(NULL, dat->ppro->m_szModuleName, szSetting, szValue);
- db_set_utf(NULL, dat->ppro->m_szModuleName, DBSETTING_XSTATUS_MSG, szValue);
- SAFE_FREE(&szValue);
-
- if (dat->ppro->m_bXStatusEnabled) {
- szValue = GetDlgItemTextUtf(hwndDlg, IDC_XTITLE);
- mir_snprintf(szSetting, "XStatus%dName", dat->bXStatus);
- db_set_utf(NULL, dat->ppro->m_szModuleName, szSetting, szValue);
- db_set_utf(NULL, dat->ppro->m_szModuleName, DBSETTING_XSTATUS_NAME, szValue);
- SAFE_FREE(&szValue);
-
- if (dat->bXStatus)
- Window_FreeIcon_IcoLib(hwndDlg);
- }
- dat->ppro->updateServerCustomStatus(TRUE);
- }
- if (dat->hEvent) UnhookEvent(dat->hEvent);
- SAFE_FREE(&dat->okButtonFormat);
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
- SAFE_FREE((void**)&dat);
- break;
-
- case WM_CLOSE:
- DestroyWindow(hwndDlg);
- break;
- }
- return FALSE;
-}
-
-void CIcqProto::setXStatusEx(BYTE bXStatus, BYTE bQuiet)
-{
- BYTE bOldXStatus = getByte(DBSETTING_XSTATUS_ID, 0);
-
- if (!m_bHideXStatusUI) {
- if (bOldXStatus <= XSTATUS_COUNT)
- Menu_ModifyItem(hXStatusItems[bOldXStatus], nullptr, INVALID_HANDLE_VALUE, 0);
-
- Menu_ModifyItem(hXStatusItems[bXStatus], nullptr, INVALID_HANDLE_VALUE, CMIF_CHECKED);
- }
-
- if (bXStatus) {
- char szSetting[64];
- char str[MAX_PATH];
- char *szName = nullptr, *szMsg = nullptr;
-
- if (m_bXStatusEnabled) {
- mir_snprintf(szSetting, "XStatus%dName", bXStatus);
- szName = getSettingStringUtf(NULL, szSetting, ICQTranslateUtfStatic(nameXStatus[bXStatus - 1], str, MAX_PATH));
- }
- mir_snprintf(szSetting, "XStatus%dMsg", bXStatus);
- szMsg = getSettingStringUtf(NULL, szSetting, "");
-
- mir_snprintf(szSetting, "XStatus%dStat", bXStatus);
- if (!bQuiet && !getByte(szSetting, 0)) {
- InitXStatusData init;
- init.ppro = this;
- init.bAction = 0; // set
- init.bXStatus = bXStatus;
- init.szXStatusName = szName;
- init.szXStatusMsg = szMsg;
- CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_SETXSTATUS), nullptr, SetXStatusDlgProc, (LPARAM)&init);
- }
- else {
- setByte(DBSETTING_XSTATUS_ID, bXStatus);
- if (m_bXStatusEnabled)
- db_set_utf(NULL, m_szModuleName, DBSETTING_XSTATUS_NAME, szName);
- db_set_utf(NULL, m_szModuleName, DBSETTING_XSTATUS_MSG, szMsg);
-
- updateServerCustomStatus(TRUE);
- }
- SAFE_FREE(&szName);
- SAFE_FREE(&szMsg);
- }
- else {
- setByte(DBSETTING_XSTATUS_ID, bXStatus);
- delSetting(DBSETTING_XSTATUS_NAME);
- delSetting(DBSETTING_XSTATUS_MSG);
-
- updateServerCustomStatus(TRUE);
- }
-}
-
-INT_PTR CIcqProto::menuXStatus(WPARAM, LPARAM, LPARAM fParam)
-{
- setXStatusEx((BYTE)fParam, 0);
- return 0;
-}
-
-void CIcqProto::InitXStatusItems(BOOL bAllowStatus)
-{
- BYTE bXStatus = getContactXStatus(NULL);
-
- if (!m_bXStatusEnabled && !m_bMoodsEnabled)
- return;
-
- if (!bAllowStatus)
- return;
-
- // Custom Status UI is disabled, no need to continue items' init
- if (m_bHideXStatusUI || m_bHideXStatusMenu)
- return;
-
- HGENMENU hRoot;
- {
- wchar_t szItem[MAX_PATH + 64];
- mir_snwprintf(szItem, TranslateT("%s Custom Status"), m_tszUserName);
-
- CMenuItem mi(&g_plugin);
- mi.root = Menu_GetProtocolMenu(m_szModuleName);
- mi.name.w = szItem;
- mi.position = 10001;
- hRoot = Menu_AddStatusMenuItem(&mi, m_szModuleName);
- }
-
- CMenuItem mi(&g_plugin);
- mi.position = 2000040000;
- mi.root = hRoot;
-
- int bXStatusMenuBuilt = 0;
- for (int i = 0; i <= XSTATUS_COUNT; i++) {
- char srvFce[MAX_PATH + 64];
- mir_snprintf(srvFce, "/menuXStatus%d", i);
- mi.position++;
-
- if (!i)
- bXStatusMenuBuilt = ProtoServiceExists(m_szModuleName, srvFce);
-
- if (!bXStatusMenuBuilt)
- CreateProtoServiceParam(srvFce, &CIcqProto::menuXStatus, i);
-
- mi.flags = (bXStatus == i ? CMIF_CHECKED : 0);
- mi.hIcolibItem = i ? hXStatusIcons[i - 1] : nullptr;
- mi.name.a = i ? (char*)nameXStatus[i - 1] : (char *)LPGEN("None");
- mi.pszService = srvFce;
-
- hXStatusItems[i] = Menu_AddStatusMenuItem(&mi, m_szModuleName);
- Menu_ShowItem(hXStatusItems[i], !(m_bHideXStatusUI || m_bHideXStatusMenu));
- }
-}
-
-void InitXStatusIcons()
-{
- wchar_t lib[2 * MAX_PATH] = { 0 };
-
- SKINICONDESC sid = {};
- sid.section.a = "Protocols/" ICQ_PROTOCOL_NAME "/" LPGEN("Custom Status");
- sid.flags = SIDF_PATH_UNICODE;
- sid.defaultFile.w = InitXStatusIconLibrary(lib, _countof(lib));
-
- for (int i = 0; i < XSTATUS_COUNT; i++) {
- char szTemp[100];
- mir_snprintf(szTemp, "icq_xstatus%d", i);
- sid.pszName = szTemp;
- sid.description.a = (LPSTR)nameXStatus[i];
- sid.iDefaultIndex = -(IDI_XSTATUS1 + i);
- hXStatusIcons[i] = g_plugin.addIcon(&sid);
- }
-
- // initialize arrays for CList custom status icons
- memset(bXStatusCListIconsValid, 0, sizeof(bXStatusCListIconsValid));
- memset(hXStatusCListIcons, -1, sizeof(hXStatusCListIcons));
-}
-
-INT_PTR CIcqProto::ShowXStatusDetails(WPARAM hContact, LPARAM)
-{
- InitXStatusData init;
- init.ppro = this;
- init.bAction = 1; // retrieve
- init.hContact = hContact;
- CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_SETXSTATUS), nullptr, SetXStatusDlgProc, (LPARAM)&init);
-
- return 0;
-}
-
-INT_PTR CIcqProto::SetXStatusEx(WPARAM, LPARAM lParam)
-{
- CUSTOM_STATUS *pData = (CUSTOM_STATUS*)lParam;
-
- if (!m_bXStatusEnabled && !m_bMoodsEnabled) return 1;
-
- if (pData->cbSize < sizeof(CUSTOM_STATUS)) return 1; // Failure
-
- if (pData->flags & CSSF_MASK_STATUS) { // set custom status
- int status = *pData->status;
-
- if (status >= 0 && status <= XSTATUS_COUNT)
- setXStatusEx((BYTE)status, 1);
- else
- return 1; // Failure
- }
-
- if (pData->flags & (CSSF_MASK_NAME | CSSF_MASK_MESSAGE)) {
- BYTE status = getContactXStatus(NULL);
-
- if (!status) return 1; // Failure
-
- if (m_bXStatusEnabled && (pData->flags & CSSF_MASK_NAME)) { // set custom status name
- if (pData->flags & CSSF_UNICODE)
- setWString(DBSETTING_XSTATUS_NAME, pData->pwszName);
- else
- setString(DBSETTING_XSTATUS_NAME, pData->pszName);
- }
- if (pData->flags & CSSF_MASK_MESSAGE) { // set custom status message
- if (pData->flags & CSSF_UNICODE)
- setWString(DBSETTING_XSTATUS_MSG, pData->pwszMessage);
- else
- setString(DBSETTING_XSTATUS_MSG, pData->pszMessage);
-
- // update status note if used for custom status message
- updateServerCustomStatus(FALSE);
- }
- }
-
- // hide menu items + contact menu item
- if (pData->flags & CSSF_DISABLE_UI)
- m_bHideXStatusUI = (*pData->wParam) ? 0 : 1;
-
- // hide menu items only
- if (pData->flags & CSSF_DISABLE_MENU)
- m_bHideXStatusMenu = (*pData->wParam) ? 0 : 1;
-
- return 0; // Success
-}
-
-INT_PTR CIcqProto::GetXStatusEx(WPARAM hContact, LPARAM lParam)
-{
- if (!m_bXStatusEnabled && !m_bMoodsEnabled)
- return 1;
-
- CUSTOM_STATUS *pData = (CUSTOM_STATUS*)lParam;
- if (pData->cbSize < sizeof(CUSTOM_STATUS))
- return 1; // Failure
-
- // fill status member
- if (pData->flags & CSSF_MASK_STATUS)
- *pData->status = getContactXStatus(hContact);
-
- // fill status name member
- if (pData->flags & CSSF_MASK_NAME) {
- if (pData->flags & CSSF_DEFAULT_NAME) {
- int status = (pData->wParam == nullptr) ? getContactXStatus(hContact) : *pData->wParam;
- if (status < 1 || status > XSTATUS_COUNT)
- return 1; // Failure
-
- if (pData->flags & CSSF_UNICODE) {
- char *text = (char*)nameXStatus[status - 1];
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, text, -1, pData->pwszName, MAX_PATH);
- }
- else mir_strcpy(pData->pszName, (char*)nameXStatus[status - 1]);
- }
- else { // moods does not support status title
- if (!m_bXStatusEnabled) return 1;
-
- if (pData->flags & CSSF_UNICODE) {
- char *str = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, "");
- WCHAR *wstr = make_unicode_string(str);
-
- mir_wstrcpy(pData->pwszName, wstr);
- SAFE_FREE(&str);
- SAFE_FREE(&wstr);
- }
- else {
- DBVARIANT dbv;
- if (!getString(hContact, DBSETTING_XSTATUS_NAME, &dbv) && dbv.pszVal) {
- mir_strcpy(pData->pszName, dbv.pszVal);
- db_free(&dbv);
- }
- else mir_strcpy(pData->pszName, "");
- }
- }
- }
-
- if (pData->flags & CSSF_MASK_MESSAGE) { // fill status message member
- if (pData->flags & CSSF_UNICODE) {
- char *str = getSettingStringUtf(hContact, CheckContactCapabilities(hContact, CAPF_STATUS_MOOD) ? DBSETTING_STATUS_NOTE : DBSETTING_XSTATUS_MSG, "");
- WCHAR *wstr = make_unicode_string(str);
-
- mir_wstrcpy(pData->pwszMessage, wstr);
- SAFE_FREE(&str);
- SAFE_FREE(&wstr);
- }
- else {
- DBVARIANT dbv = { 0 };
-
- if (!getString(hContact, CheckContactCapabilities(hContact, CAPF_STATUS_MOOD) ? DBSETTING_STATUS_NOTE : DBSETTING_XSTATUS_MSG, &dbv) && dbv.pszVal)
- mir_strcpy(pData->pszMessage, dbv.pszVal);
- else
- mir_strcpy(pData->pszMessage, "");
-
- db_free(&dbv);
- }
- }
-
- if (pData->flags & CSSF_DISABLE_UI)
- if (pData->wParam)
- *pData->wParam = !m_bHideXStatusUI;
-
- if (pData->flags & CSSF_DISABLE_MENU)
- if (pData->wParam)
- *pData->wParam = !m_bHideXStatusMenu;
-
- if (pData->flags & CSSF_STATUSES_COUNT)
- if (pData->wParam)
- *pData->wParam = XSTATUS_COUNT;
-
- if (pData->flags & CSSF_STR_SIZES) {
- DBVARIANT dbv = { DBVT_DELETED };
-
- if (pData->wParam) {
- if (m_bXStatusEnabled && !getString(hContact, DBSETTING_XSTATUS_NAME, &dbv))
- *pData->wParam = mir_strlen(dbv.pszVal);
- else
- *pData->wParam = 0;
- db_free(&dbv);
- }
-
- if (pData->lParam) {
- if (!getString(hContact, CheckContactCapabilities(hContact, CAPF_STATUS_MOOD) ? DBSETTING_STATUS_NOTE : DBSETTING_XSTATUS_MSG, &dbv))
- *pData->lParam = mir_strlen(dbv.pszVal);
- else
- *pData->lParam = 0;
- db_free(&dbv);
- }
- }
-
- return 0; // Success
-}
-
-INT_PTR CIcqProto::GetXStatusIcon(WPARAM wParam, LPARAM lParam)
-{
- if (!m_bXStatusEnabled && !m_bMoodsEnabled)
- return 0;
-
- if (!wParam)
- wParam = getContactXStatus(NULL);
-
- if (wParam >= 1 && wParam <= XSTATUS_COUNT)
- return (INT_PTR)getXStatusIcon((BYTE)wParam, lParam);
-
- return 0;
-}
-
-INT_PTR CIcqProto::RequestXStatusDetails(WPARAM hContact, LPARAM)
-{
- if (!m_bXStatusEnabled)
- return 0;
-
- // user has xstatus, no auto-retrieve details, valid contact, request details
- if (hContact && !getByte("XStatusAuto", DEFAULT_XSTATUS_AUTO) && getContactXStatus(hContact) && CheckContactCapabilities(hContact, CAPF_XSTATUS))
- return requestXStatusDetails(hContact, TRUE);
-
- return 0;
-}
-
-INT_PTR CIcqProto::RequestAdvStatusIconIdx(WPARAM wParam, LPARAM)
-{
- if (!m_bXStatusEnabled && !m_bMoodsEnabled)
- return -1;
-
- BYTE bXStatus = getContactXStatus(wParam);
- if (bXStatus) {
- if (!bXStatusCListIconsValid[bXStatus - 1]) { // adding icon
- int idx = hXStatusCListIcons[bXStatus - 1];
- HIMAGELIST hCListImageList = Clist_GetImageList();
- if (hCListImageList) {
- HICON hXStatusIcon = getXStatusIcon(bXStatus, LR_SHARED);
-
- if (idx > 0)
- ImageList_ReplaceIcon(hCListImageList, idx, hXStatusIcon);
- else
- hXStatusCListIcons[bXStatus - 1] = ImageList_AddIcon(hCListImageList, hXStatusIcon);
- // mark icon index in the array as valid
- bXStatusCListIconsValid[bXStatus - 1] = TRUE;
-
- IcoLib_ReleaseIcon(hXStatusIcon);
- }
- }
-
- int idx = bXStatusCListIconsValid[bXStatus - 1] ? hXStatusCListIcons[bXStatus - 1] : -1;
- if (idx > 0)
- return (idx & 0xFFFF) << 16;
- }
- return -1;
-}
diff --git a/protocols/IcqOscarJ/src/icq_xtraz.cpp b/protocols/IcqOscarJ/src/icq_xtraz.cpp
deleted file mode 100644
index 5bf67c4095..0000000000
--- a/protocols/IcqOscarJ/src/icq_xtraz.cpp
+++ /dev/null
@@ -1,400 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Internal Xtraz API
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::handleXtrazNotify(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szMsg, size_t nMsgLen, BOOL bThruDC)
-{
- char *szNotify = strstrnull(szMsg, "<NOTIFY>");
- char *szQuery = strstrnull(szMsg, "<QUERY>");
-
- MCONTACT hContact = HContactFromUIN(dwUin, nullptr);
- if (hContact) // user sent us xtraz, he supports it
- SetContactCapabilities(hContact, CAPF_XTRAZ);
-
- if (szNotify && szQuery) { // valid request
- char *szWork, *szEnd;
- int nNotifyLen, nQueryLen;
-
- szNotify += 8;
- szQuery += 7;
- szEnd = strstrnull(szMsg, "</NOTIFY>");
- if (!szEnd) szEnd = szMsg + nMsgLen;
- nNotifyLen = (szEnd - szNotify);
- szEnd = strstrnull(szMsg, "</QUERY>");
- if (!szEnd) szEnd = szNotify;
- szNotify = DemangleXml(szNotify, nNotifyLen);
- nQueryLen = (szEnd - szQuery);
- szQuery = DemangleXml(szQuery, nQueryLen);
- szWork = strstrnull(szQuery, "<PluginID>");
- szEnd = strstrnull(szQuery, "</PluginID>");
-
- debugLogA("Query: %s", szQuery);
- debugLogA("Notify: %s", szNotify);
-
- if (szWork && szEnd) { // this is our plugin
- szWork += 10;
- *szEnd = '\0';
-
- if (!mir_strcmpi(szWork, "srvMng") && strstrnull(szNotify, "AwayStat")) {
- char *szSender = strstrnull(szNotify, "<senderId>");
- char *szEndSend = strstrnull(szNotify, "</senderId>");
-
- if (szSender && szEndSend) {
- szSender += 10;
- *szEndSend = '\0';
-
- if ((DWORD)atoi(szSender) == dwUin) {
- BYTE dwXId = m_bXStatusEnabled ? getContactXStatus(NULL) : 0;
-
- if (dwXId && validateStatusMessageRequest(hContact, MTYPE_SCRIPT_NOTIFY)) { // apply privacy rules
- NotifyEventHooks(m_modeMsgsEvent, (WPARAM)MTYPE_SCRIPT_NOTIFY, (LPARAM)dwUin);
-
- char *tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_NAME, "");
- char *szXName = MangleXml(tmp, mir_strlen(tmp));
- SAFE_FREE(&tmp);
-
- tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, "");
- char *szXMsg = MangleXml(tmp, mir_strlen(tmp));
- SAFE_FREE(&tmp);
-
- size_t nResponseLen = 212 + mir_strlen(szXName) + mir_strlen(szXMsg) + UINMAXLEN + 2;
- char *szResponse = (char*)_alloca(nResponseLen + 1);
- // send response
- mir_snprintf(szResponse, nResponseLen,
- "<ret event=\"OnRemoteNotification\">"
- "<srv><id>cAwaySrv</id>"
- "<val srv_id=\"cAwaySrv\"><Root>"
- "<CASXtraSetAwayMessage></CASXtraSetAwayMessage>"
- "<uin>%d</uin>"
- "<index>%d</index>"
- "<title>%s</title>"
- "<desc>%s</desc></Root></val></srv></ret>",
- m_dwLocalUIN, dwXId, szXName, szXMsg);
-
- SAFE_FREE(&szXName);
- SAFE_FREE(&szXMsg);
-
- struct rates_xstatus_response : public rates_queue_item
- {
- protected:
- virtual rates_queue_item* copyItem(rates_queue_item *aDest = nullptr)
- {
- rates_xstatus_response *pDest = (rates_xstatus_response*)aDest;
- if (!pDest)
- pDest = new rates_xstatus_response(ppro, wGroup);
-
- pDest->bThruDC = bThruDC;
- pDest->dwMsgID1 = dwMsgID1;
- pDest->dwMsgID2 = dwMsgID2;
- pDest->wCookie = wCookie;
- pDest->szResponse = null_strdup(szResponse);
-
- return rates_queue_item::copyItem(pDest);
- };
- public:
- rates_xstatus_response(CIcqProto *ppro, WORD wGroup) : rates_queue_item(ppro, wGroup), szResponse(nullptr) {};
- virtual ~rates_xstatus_response() { if (bCreated) SAFE_FREE(&szResponse); };
-
- virtual void execute()
- {
- ppro->SendXtrazNotifyResponse(dwUin, dwMsgID1, dwMsgID2, wCookie, szResponse, mir_strlen(szResponse), bThruDC);
- };
-
- BOOL bThruDC;
- DWORD dwMsgID1;
- DWORD dwMsgID2;
- WORD wCookie;
- char *szResponse;
- };
-
- WORD wGroup;
- {
- mir_cslock rlck(m_ratesMutex);
- wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE);
- }
-
- rates_xstatus_response rr(this, wGroup);
- rr.hContact = hContact;
- rr.dwUin = dwUin;
- rr.bThruDC = bThruDC;
- rr.dwMsgID1 = dwMID;
- rr.dwMsgID2 = dwMID2;
- rr.wCookie = wCookie;
- rr.szResponse = szResponse;
-
- handleRateItem(&rr, RQT_RESPONSE, 0, !bThruDC);
- }
- else if (dwXId)
- debugLogA("Privacy: Ignoring XStatus request");
- else
- debugLogA("Error: We are not in XStatus, skipping");
- }
- else debugLogA("Error: Invalid sender information");
- }
- else debugLogA("Error: Missing sender information");
- }
- else debugLogA("Error: Unknown plugin \"%s\" in Xtraz message", szWork);
- }
- else debugLogA("Error: Missing PluginID in Xtraz message");
-
- SAFE_FREE(&szNotify);
- SAFE_FREE(&szQuery);
- }
- else debugLogA("Error: Invalid Xtraz Notify message");
-}
-
-void CIcqProto::handleXtrazNotifyResponse(MCONTACT hContact, WORD wCookie, char* szMsg)
-{
- char *szMem, *szRes, *szEnd;
- size_t nResLen;
-
- debugLogA("Received Xtraz Notify Response");
-
- szRes = strstrnull(szMsg, "<RES>");
- szEnd = strstrnull(szMsg, "</RES>");
-
- if (szRes && szEnd) { // valid response
- char *szNode, *szWork;
-
- szRes += 5;
- nResLen = szEnd - szRes;
-
- szMem = szRes = DemangleXml(szRes, nResLen);
-
- debugLogA("Response: %s", szRes);
-
- ProtoBroadcastAck(hContact, ICQACKTYPE_XTRAZNOTIFY_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, (LPARAM)szRes);
-
-NextVal:
- szNode = strstrnull(szRes, "<val srv_id=");
- if (szNode) szEnd = strstrnull(szNode, ">"); else szEnd = nullptr;
-
- if (szNode && szEnd) {
- *(szEnd - 1) = '\0';
- szNode += 13; //one more than the length of the string to skip ' or " too
- szWork = szEnd + 1;
-
- if (!mir_strcmpi(szNode, "cAwaySrv")) {
- int bChanged = FALSE;
-
- *szEnd = ' ';
- szNode = strstrnull(szWork, "<index>");
- szEnd = strstrnull(szWork, "</index>");
- if (szNode && szEnd) {
- szNode += 7;
- *szEnd = '\0';
- if (atoi(szNode) != getContactXStatus(hContact)) { // this is strange - but go on
- debugLogA("Warning: XStatusIds do not match!");
- }
- *szEnd = ' ';
- }
- szNode = strstrnull(szWork, "<title>");
- szEnd = strstrnull(szWork, "</title>");
- if (szNode && szEnd) { // we got XStatus title, save it
- char *szXName, *szOldXName;
- szNode += 7;
- *szEnd = '\0';
- szXName = DemangleXml(szNode, mir_strlen(szNode));
- // check if the name changed
- szOldXName = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, nullptr);
- if (mir_strcmp(szOldXName, szXName))
- bChanged = TRUE;
- SAFE_FREE(&szOldXName);
- db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_NAME, szXName);
- SAFE_FREE(&szXName);
- *szEnd = ' ';
- }
- szNode = strstrnull(szWork, "<desc>");
- szEnd = strstrnull(szWork, "</desc>");
- if (szNode && szEnd) { // we got XStatus mode msg, save it
- char *szXMsg, *szOldXMsg;
- szNode += 6;
- *szEnd = '\0';
- szXMsg = DemangleXml(szNode, mir_strlen(szNode));
- // check if the decription changed
- szOldXMsg = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, nullptr);
- if (mir_strcmp(szOldXMsg, szXMsg))
- bChanged = TRUE;
- SAFE_FREE(&szOldXMsg);
- db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_MSG, szXMsg);
- SAFE_FREE(&szXMsg);
- }
- ProtoBroadcastAck(hContact, ICQACKTYPE_XSTATUS_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0);
- }
- else {
- char *szSrvEnd = strstrnull(szEnd, "</srv>");
-
- if (szSrvEnd && strstrnull(szSrvEnd, "<val srv_id=")) { // check all values !
- szRes = szSrvEnd + 6; // after first value
- goto NextVal;
- }
- // no next val, we were unable to handle packet, write error
- debugLogA("Error: Unknown serverId \"%s\" in Xtraz response", szNode);
- }
- }
- else debugLogA("Error: Missing serverId in Xtraz response");
-
- SAFE_FREE(&szMem);
- }
- else debugLogA("Error: Invalid Xtraz Notify response");
-}
-
-static char* getXmlPidItem(const char* szData)
-{
- const char *szPid = strstrnull(szData, "<PID>");
- const char *szEnd = strstrnull(szData, "</PID>");
-
- if (szPid && szEnd) {
- szPid += 5;
- return DemangleXml(szPid, szEnd - szPid);
- }
- return nullptr;
-}
-
-void CIcqProto::handleXtrazInvitation(DWORD dwUin, char* szMsg, BOOL bThruDC)
-{
- MCONTACT hContact = HContactFromUIN(dwUin, nullptr);
- if (hContact) // user sent us xtraz, he supports it
- SetContactCapabilities(hContact, CAPF_XTRAZ);
-
- char *szPluginID = getXmlPidItem(szMsg);
- if (!mir_strcmp(szPluginID, "ICQChatRecv")) // it is a invitation to multi-user chat
- ;
- else
- NetLog_Uni(bThruDC, "Error: Unknown plugin \"%s\" in Xtraz message", szPluginID);
-
- SAFE_FREE(&szPluginID);
-}
-
-void CIcqProto::handleXtrazData(DWORD dwUin, char* szMsg, BOOL bThruDC)
-{
- MCONTACT hContact = HContactFromUIN(dwUin, nullptr);
- if (hContact) // user sent us xtraz, he supports it
- SetContactCapabilities(hContact, CAPF_XTRAZ);
-
- char *szPluginID = getXmlPidItem(szMsg);
- if (!mir_strcmp(szPluginID, "viewCard")) { // it is a greeting card
- char *szWork, *szEnd, *szUrl, *szNum;
-
- szWork = strstrnull(szMsg, "<InD>");
- szEnd = strstrnull(szMsg, "</InD>");
- if (szWork && szEnd) {
- int nDataLen = szEnd - szWork;
-
- szUrl = (char*)_alloca(nDataLen);
- memcpy(szUrl, szWork + 5, nDataLen);
- szUrl[nDataLen - 5] = '\0';
-
- if (!_strnicmp(szUrl, "view_", 5)) {
- szNum = szUrl + 5;
- szWork = strstrnull(szUrl, ".html");
- if (szWork) {
- mir_strcpy(szWork, ".php");
- mir_strcat(szWork, szWork + 5);
- }
- while (szWork = strstrnull(szUrl, "&amp;")) // unescape &amp; code
- mir_strcpy(szWork + 1, szWork + 5);
-
- szWork = (char*)SAFE_MALLOC(nDataLen + MAX_PATH);
- ICQTranslateUtfStatic(LPGEN("Greeting card:"), szWork, MAX_PATH);
- mir_strcat(szWork, "\r\nhttp://www.icq.com/friendship/pages/view_page_");
- mir_strcat(szWork, szNum);
-
- // Create message to notify user
- PROTORECVEVENT pre = { 0 };
- pre.timestamp = time(0);
- pre.szMessage = szWork;
-
- int bAdded;
- ProtoChainRecvMsg(HContactFromUIN(dwUin, &bAdded), &pre);
-
- SAFE_FREE(&szWork);
- }
- else NetLog_Uni(bThruDC, "Error: Non-standard greeting card message");
- }
- else NetLog_Uni(bThruDC, "Error: Malformed greeting card message");
- }
- else NetLog_Uni(bThruDC, "Error: Unknown plugin \"%s\" in Xtraz message", szPluginID);
-
- SAFE_FREE(&szPluginID);
-}
-
-// Functions really sending Xtraz stuff
-DWORD CIcqProto::SendXtrazNotifyRequest(MCONTACT hContact, char* szQuery, char* szNotify, int bForced)
-{
- DWORD dwUin;
- if (getContactUid(hContact, &dwUin, nullptr))
- return 0; // Invalid contact
-
- if (!CheckContactCapabilities(hContact, CAPF_XTRAZ) && !bForced)
- return 0; // Contact does not support xtraz, do not send anything
-
- char *szQueryBody = MangleXml(szQuery, mir_strlen(szQuery));
- char *szNotifyBody = MangleXml(szNotify, mir_strlen(szNotify));
- size_t nBodyLen = mir_strlen(szQueryBody) + mir_strlen(szNotifyBody) + 41;
- char *szBody = (char*)_alloca(nBodyLen);
- nBodyLen = mir_snprintf(szBody, nBodyLen, "<N><QUERY>%s</QUERY><NOTIFY>%s</NOTIFY></N>", szQueryBody, szNotifyBody);
- SAFE_FREE((void**)&szQueryBody);
- SAFE_FREE((void**)&szNotifyBody);
-
- // Set up the ack type
- cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_SCRIPT_NOTIFY, ACKTYPE_CLIENT);
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
-
- // have we a open DC, send through that
- if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0))
- icq_sendXtrazRequestDirect(hContact, dwCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY);
- else
- icq_sendXtrazRequestServ(dwUin, dwCookie, szBody, nBodyLen, pCookieData);
-
- return dwCookie;
-}
-
-void CIcqProto::SendXtrazNotifyResponse(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szResponse, size_t nResponseLen, BOOL bThruDC)
-{
- char *szResBody = MangleXml(szResponse, nResponseLen);
- size_t nBodyLen = mir_strlen(szResBody) + 21;
- char *szBody = (char*)_alloca(nBodyLen);
- MCONTACT hContact = HContactFromUIN(dwUin, nullptr);
-
- if (hContact != INVALID_CONTACT_ID && !CheckContactCapabilities(hContact, CAPF_XTRAZ)) {
- SAFE_FREE(&szResBody);
- return; // Contact does not support xtraz, do not send anything
- }
-
- nBodyLen = mir_snprintf(szBody, nBodyLen, "<NR><RES>%s</RES></NR>", szResBody);
- SAFE_FREE(&szResBody);
-
- // Was request received thru DC and have we a open DC, send through that
- if (bThruDC && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0))
- icq_sendXtrazResponseDirect(hContact, wCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY);
- else
- icq_sendXtrazResponseServ(dwUin, dwMID, dwMID2, wCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY);
-}
diff --git a/protocols/IcqOscarJ/src/icqosc_svcs.cpp b/protocols/IcqOscarJ/src/icqosc_svcs.cpp
deleted file mode 100644
index d84a66fcf4..0000000000
--- a/protocols/IcqOscarJ/src/icqosc_svcs.cpp
+++ /dev/null
@@ -1,679 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// High-level code for exported API services
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-INT_PTR CIcqProto::AddServerContact(WPARAM hContact, LPARAM)
-{
- if (!m_bSsiEnabled) return 0;
-
- // Does this contact have a UID?
- DWORD dwUin;
- uid_str szUid;
- if (!getContactUid(hContact, &dwUin, &szUid) && !getWord(hContact, DBSETTING_SERVLIST_ID, 0) && !getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0)) {
- /// TODO: remove possible 0x6A TLV in contact server-list data!!!
- // Read group from DB
- char *pszGroup = getContactCListGroup(hContact);
-
- servlistAddContact(hContact, pszGroup);
- SAFE_FREE((void**)&pszGroup);
- }
- return 0;
-}
-
-static int LookupDatabaseSetting(const FieldNamesItem* table, int code, DBVARIANT *dbv, BYTE type)
-{
- char *text = LookupFieldName(table, code);
- if (!text) {
- dbv->type = DBVT_DELETED;
- return 1;
- }
-
- if (type == DBVT_ASCIIZ) {
- dbv->pszVal = mir_strdup(Translate(text));
- dbv->type = DBVT_ASCIIZ;
- }
- else if (type == DBVT_UTF8 || !type) {
- char tmp[MAX_PATH];
- dbv->pszVal = mir_strdup(ICQTranslateUtfStatic(text, tmp, MAX_PATH));
- dbv->type = DBVT_UTF8;
- }
- else if (type == DBVT_WCHAR) {
- WCHAR* wtext = make_unicode_string(text);
- dbv->pwszVal = mir_wstrdup(TranslateW(wtext));
- dbv->type = DBVT_WCHAR;
- SAFE_FREE((void**)&wtext);
- }
- return 0; // Success
-}
-
-INT_PTR CIcqProto::GetInfoSetting(WPARAM hContact, LPARAM lParam)
-{
- DBCONTACTGETSETTING *cgs = (DBCONTACTGETSETTING*)lParam;
- BYTE type = cgs->pValue->type;
- INT_PTR rc = db_get_s(hContact, cgs->szModule, cgs->szSetting, cgs->pValue, 0);
- if (rc)
- return rc;
-
- // Success
- DBVARIANT dbv = *cgs->pValue;
- if (dbv.type == DBVT_BLOB) {
- cgs->pValue->pbVal = (BYTE*)mir_alloc(dbv.cpbVal);
- memcpy(cgs->pValue->pbVal, dbv.pbVal, dbv.cpbVal);
- }
- else if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) {
- // convert to the desired type
- if (!type)
- type = dbv.type;
-
- // type is correct, only move it to miranda's heap
- if (dbv.type == type)
- cgs->pValue->pszVal = mir_strdup(dbv.pszVal);
- else if (type == DBVT_WCHAR) {
- if (dbv.type != DBVT_UTF8) {
- int len = MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, nullptr, 0);
- cgs->pValue->pwszVal = (WCHAR*)mir_alloc((len + 1) * sizeof(WCHAR));
- if (cgs->pValue->pwszVal == nullptr)
- rc = 1;
- else {
- MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, cgs->pValue->pwszVal, len);
- cgs->pValue->pwszVal[len] = '\0';
- }
- }
- else {
- char *savePtr = dbv.pszVal ? mir_strcpy((char*)_alloca(mir_strlen(dbv.pszVal) + 1), dbv.pszVal) : nullptr;
- if (!mir_utf8decode(savePtr, &cgs->pValue->pwszVal))
- rc = 1;
- }
- }
- else if (type == DBVT_UTF8) {
- cgs->pValue->pszVal = mir_utf8encode(dbv.pszVal);
- if (cgs->pValue->pszVal == nullptr)
- rc = 1;
- }
- else if (type == DBVT_ASCIIZ) {
- cgs->pValue->pszVal = mir_strdup(dbv.pszVal);
- mir_utf8decode(cgs->pValue->pszVal, nullptr);
- }
-
- cgs->pValue->type = type;
- }
- else if (!mir_strcmp(cgs->szModule, m_szModuleName) && (dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD)) {
- int code = (dbv.type == DBVT_BYTE) ? dbv.bVal : ((dbv.type == DBVT_WORD) ? dbv.wVal : dbv.dVal);
-
- if (!mir_strcmp(cgs->szSetting, "Language1") || !mir_strcmp(cgs->szSetting, "Language2") || !mir_strcmp(cgs->szSetting, "Language3"))
- rc = LookupDatabaseSetting(languageField, code, cgs->pValue, type);
- else if (!mir_strcmp(cgs->szSetting, "Country") || !mir_strcmp(cgs->szSetting, "OriginCountry") || !mir_strcmp(cgs->szSetting, "CompanyCountry")) {
- if (code == 420) code = 42; // conversion of obsolete codes (OMG!)
- else if (code == 421) code = 4201;
- else if (code == 102) code = 1201;
- rc = LookupDatabaseSetting(countryField, code, cgs->pValue, type);
- }
- else if (!mir_strcmp(cgs->szSetting, "Gender"))
- rc = LookupDatabaseSetting(genderField, code, cgs->pValue, type);
- else if (!mir_strcmp(cgs->szSetting, "MaritalStatus"))
- rc = LookupDatabaseSetting(maritalField, code, cgs->pValue, type);
- else if (!mir_strcmp(cgs->szSetting, "StudyLevel"))
- rc = LookupDatabaseSetting(studyLevelField, code, cgs->pValue, type);
- else if (!mir_strcmp(cgs->szSetting, "CompanyIndustry"))
- rc = LookupDatabaseSetting(industryField, code, cgs->pValue, type);
- else if (!mir_strcmp(cgs->szSetting, "Interest0Cat") || !mir_strcmp(cgs->szSetting, "Interest1Cat") || !mir_strcmp(cgs->szSetting, "Interest2Cat") || !mir_strcmp(cgs->szSetting, "Interest3Cat"))
- rc = LookupDatabaseSetting(interestsField, code, cgs->pValue, type);
- }
- // Release database memory
- db_free(&dbv);
- return rc;
-}
-
-INT_PTR CIcqProto::ChangeInfoEx(WPARAM wParam, LPARAM)
-{
- if (!icqOnline() || !wParam)
- return 0;
-
- PBYTE buf = nullptr;
- size_t buflen = 0;
-
- // userinfo
- ppackTLVWord(&buf, &buflen, 0x1C2, (WORD)GetACP());
-
- if (wParam & CIXT_CONTACT) { // contact information
- BYTE *pBlock = nullptr;
- size_t cbBlock = 0;
- int nItems = 0;
-
- // Emails
- nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "e-mail0", 0x78, 0x64, 0x00);
- nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "e-mail1", 0x78, 0x64, 0x00);
- nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "e-mail2", 0x78, 0x64, 0x00);
- ppackTLVBlockItems(&buf, &buflen, 0x8C, &nItems, &pBlock, (WORD*)&cbBlock, FALSE);
-
- // Phones
- nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "Phone", 0x6E, 0x64, 0x01);
- nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "CompanyPhone", 0x6E, 0x64, 0x02);
- nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "Cellular", 0x6E, 0x64, 0x03);
- nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "Fax", 0x6E, 0x64, 0x04);
- nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "CompanyFax", 0x6E, 0x64, 0x05);
- ppackTLVBlockItems(&buf, &buflen, 0xC8, &nItems, &pBlock, (WORD*)&cbBlock, FALSE);
-
- ppackTLVByte(&buf, &buflen, 0x1EA, getByte("AllowSpam", 0));
- }
-
- if (wParam & CIXT_BASIC) { // upload basic user info
- ppackTLVStringUtfFromDB(&buf, &buflen, "Nick", 0x78);
- ppackTLVStringUtfFromDB(&buf, &buflen, "FirstName", 0x64);
- ppackTLVStringUtfFromDB(&buf, &buflen, "LastName", 0x6E);
- ppackTLVStringUtfFromDB(&buf, &buflen, "About", 0x186);
- }
-
- if (wParam & CIXT_MORE) {
- BYTE b = getByte("Gender", 0);
- ppackTLVByte(&buf, &buflen, 0x82, (BYTE)(b ? (b == 'M' ? 2 : 1) : 0));
-
- ppackTLVDateFromDB(&buf, &buflen, "BirthYear", "BirthMonth", "BirthDay", 0x1A4);
-
- ppackTLVWord(&buf, &buflen, 0xAA, getByte("Language1", 0));
- ppackTLVWord(&buf, &buflen, 0xB4, getByte("Language2", 0));
- ppackTLVWord(&buf, &buflen, 0xBE, getByte("Language3", 0));
-
- ppackTLVWord(&buf, &buflen, 0x12C, getByte("MaritalStatus", 0));
- }
-
- if (wParam & CIXT_WORK) {
- BYTE *pBlock = nullptr;
- size_t cbBlock = 0;
- int nItems = 1;
-
- // Jobs
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyPosition", 0x64);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "Company", 0x6E);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyDepartment", 0x7D);
- ppackTLVStringFromDB(&pBlock, &cbBlock, "CompanyHomepage", 0x78);
- ppackTLVWord(&pBlock, &cbBlock, 0x82, getWord("CompanyIndustry", 0));
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyStreet", 0xAA);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyCity", 0xB4);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyState", 0xBE);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyZIP", 0xC8);
- ppackTLVDWord(&pBlock, &cbBlock, 0xD2, getWord("CompanyCountry", 0));
- /// TODO: pack unknown data (need to preserve them in Block Items)
- ppackTLVBlockItems(&buf, &buflen, 0x118, &nItems, &pBlock, (WORD*)&cbBlock, TRUE);
-
- // ppackTLVWord(&buf, &buflen, getWord("CompanyOccupation", 0), TLV_OCUPATION, 1); // Lost In Conversion
- }
-
- if (wParam & CIXT_EDUCATION) {
- BYTE *pBlock = nullptr;
- size_t cbBlock = 0;
- int nItems = 1;
-
- // Studies
- ppackTLVWord(&pBlock, &cbBlock, 0x64, getWord("StudyLevel", 0));
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "StudyInstitute", 0x6E);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "StudyDegree", 0x78);
- ppackTLVWord(&pBlock, &cbBlock, 0x8C, getWord("StudyYear", 0));
- ppackTLVBlockItems(&buf, &buflen, 0x10E, &nItems, &pBlock, (WORD*)&cbBlock, TRUE);
- }
-
- if (wParam & CIXT_LOCATION) {
- BYTE *pBlock = nullptr;
- size_t cbBlock = 0;
- int nItems = 1;
-
- // Home Address
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "Street", 0x64);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "City", 0x6E);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "State", 0x78);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "ZIP", 0x82);
- ppackTLVDWord(&pBlock, &cbBlock, 0x8C, getWord("Country", 0));
- ppackTLVBlockItems(&buf, &buflen, 0x96, &nItems, &pBlock, (WORD*)&cbBlock, TRUE);
-
- nItems = 1;
- // Origin Address
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "OriginStreet", 0x64);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "OriginCity", 0x6E);
- ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "OriginState", 0x78);
- ppackTLVDWord(&pBlock, &cbBlock, 0x8C, getWord("OriginCountry", 0));
- ppackTLVBlockItems(&buf, &buflen, 0xA0, &nItems, &pBlock, (WORD*)&cbBlock, TRUE);
-
- ppackTLVStringFromDB(&buf, &buflen, "Homepage", 0xFA);
-
- // Timezone
- WORD wTimezone = getByte("Timezone", 0);
- if ((wTimezone & 0x0080) == 0x80) wTimezone |= 0xFF00; // extend signed number
- ppackTLVWord(&buf, &buflen, 0x17C, wTimezone);
- }
-
- if (wParam & CIXT_BACKGROUND) {
- BYTE *pBlock = nullptr;
- size_t cbBlock = 0;
- int nItems = 0;
-
- // Interests
- nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest0Text", 0x6E, 0x64, getWord("Interest0Cat", 0));
- nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest1Text", 0x6E, 0x64, getWord("Interest1Cat", 0));
- nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest2Text", 0x6E, 0x64, getWord("Interest2Cat", 0));
- nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest3Text", 0x6E, 0x64, getWord("Interest3Cat", 0));
- ppackTLVBlockItems(&buf, &buflen, 0x122, &nItems, &pBlock, (WORD*)&cbBlock, FALSE);
- }
-
- DWORD dwCookie = icq_changeUserDirectoryInfoServ(buf, buflen, DIRECTORYREQUEST_UPDATEOWNER);
-
- SAFE_FREE((void**)&buf);
-
- return dwCookie;
-}
-
-INT_PTR CIcqProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
-{
- if (wParam == AF_MAXSIZE) {
- POINT *size = (POINT*)lParam;
- if (size) {
- size->x = 64;
- size->y = 64;
- }
- return 0;
- }
-
- if (wParam == AF_PROPORTION)
- return PIP_NONE;
-
- if (wParam == AF_FORMATSUPPORTED)
- return (lParam == PA_FORMAT_JPEG || lParam == PA_FORMAT_GIF || lParam == PA_FORMAT_XML || lParam == PA_FORMAT_BMP);
-
- if (wParam == AF_ENABLED)
- return (m_bSsiEnabled && m_bAvatarsEnabled);
-
- if (wParam == AF_DONTNEEDDELAYS)
- return 0;
-
- // server accepts images of 7168 bytees, not bigger
- if (wParam == AF_MAXFILESIZE)
- return 7168;
-
- // do not request avatar again if server gave an error
- if (wParam == AF_DELAYAFTERFAIL)
- return 1 * 60 * 60 * 1000; // one hour
-
- // avatars can be fetched all the time (server only operation)
- if (wParam == AF_FETCHIFPROTONOTVISIBLE || wParam == AF_FETCHIFCONTACTOFFLINE)
- return 1;
-
- return 0;
-}
-
-INT_PTR CIcqProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
-{
- PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;
- DWORD dwUIN;
- uid_str szUID;
- DBVARIANT dbv = { DBVT_DELETED };
-
- if (!m_bAvatarsEnabled) return GAIR_NOAVATAR;
-
- if (getSetting(pai->hContact, "AvatarHash", &dbv) || dbv.type != DBVT_BLOB || (dbv.cpbVal != 0x14 && dbv.cpbVal != 0x09)) {
- db_free(&dbv);
- return GAIR_NOAVATAR; // we did not found avatar hash or hash invalid - no avatar available
- }
-
- if (getContactUid(pai->hContact, &dwUIN, &szUID)) {
- db_free(&dbv);
- return GAIR_NOAVATAR; // we do not support avatars for invalid contacts
- }
-
- int dwPaFormat = getByte(pai->hContact, "AvatarType", PA_FORMAT_UNKNOWN);
-
- if (dwPaFormat != PA_FORMAT_UNKNOWN) { // we know the format, test file
- wchar_t tszFile[MAX_PATH * 2 + 4];
-
- GetFullAvatarFileName(dwUIN, szUID, dwPaFormat, tszFile, MAX_PATH * 2);
-
- mir_wstrncpy(pai->filename, tszFile, _countof(pai->filename)); // Avatar API does not support unicode :-(
- pai->format = dwPaFormat;
-
- if (!IsAvatarChanged(pai->hContact, dbv.pbVal, dbv.cpbVal)) { // hashes are the same
- if (_waccess(tszFile, 0) == 0) {
- db_free(&dbv);
-
- return GAIR_SUCCESS; // we have found the avatar file, whoala
- }
- }
- }
-
- if (IsAvatarChanged(pai->hContact, dbv.pbVal, dbv.cpbVal)) { // we didn't received the avatar before - this ensures we will not request avatar again and again
- if ((wParam & GAIF_FORCE) != 0 && pai->hContact != 0) { // request avatar data
- wchar_t tszFile[MAX_PATH * 2 + 4];
-
- GetAvatarFileName(dwUIN, szUID, tszFile, MAX_PATH * 2);
- GetAvatarData(pai->hContact, dwUIN, szUID, dbv.pbVal, dbv.cpbVal, tszFile);
- mir_wstrncpy(pai->filename, tszFile, _countof(pai->filename)); // Avatar API does not support unicode :-(
-
- db_free(&dbv);
-
- return GAIR_WAITFOR;
- }
- }
- db_free(&dbv);
-
- return GAIR_NOAVATAR;
-}
-
-
-INT_PTR CIcqProto::GetMyAvatar(WPARAM wParam, LPARAM lParam)
-{
- if (!m_bAvatarsEnabled) return -2;
-
- if (!wParam) return -3;
-
- wchar_t *tszFile = GetOwnAvatarFileName();
- if (tszFile && !_waccess(tszFile, 0)) {
- wcsncpy((wchar_t*)wParam, tszFile, (int)lParam);
- SAFE_FREE(&tszFile);
- return 0;
- }
-
- SAFE_FREE(&tszFile);
- return -1;
-}
-
-
-INT_PTR CIcqProto::GrantAuthorization(WPARAM wParam, LPARAM)
-{
- if (icqOnline() && wParam != 0) {
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(wParam, &dwUin, &szUid))
- return 0; // Invalid contact
-
- // send without reason, do we need any ?
- icq_sendGrantAuthServ(dwUin, szUid, nullptr);
- // auth granted, remove contact menu item
- delSetting(wParam, "Grant");
- }
-
- return 0;
-}
-
-int CIcqProto::OnIdleChanged(WPARAM, LPARAM lParam)
-{
- int bIdle = (lParam & IDF_ISIDLE);
- int bPrivacy = (lParam & IDF_PRIVACY);
- if (bPrivacy) {
- debugLogA("ICQ: idle mode ignored due to the private mode: %08x", lParam);
- return 0;
- }
-
- setDword("IdleTS", bIdle ? time(0) : 0);
-
- if (m_bTempVisListEnabled) // remove temporary visible users
- sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_REMOVETEMPVISIBLE, BUL_TEMPVISIBLE);
-
- icq_setidle(bIdle != 0);
- return 0;
-}
-
-INT_PTR CIcqProto::RevokeAuthorization(WPARAM wParam, LPARAM)
-{
- if (icqOnline() && wParam != 0) {
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(wParam, &dwUin, &szUid))
- return 0; // Invalid contact
-
- if (MessageBox(nullptr, TranslateT("Are you sure you want to revoke user's authorization?\nThis will remove you from his/her list on some clients."), TranslateT("Confirmation"), MB_ICONQUESTION | MB_YESNO) != IDYES)
- return 0;
-
- icq_sendRevokeAuthServ(dwUin, szUid);
- }
-
- return 0;
-}
-
-
-INT_PTR CIcqProto::SendSms(WPARAM wParam, LPARAM lParam)
-{
- if (icqOnline() && wParam && lParam)
- return icq_sendSMSServ((const char *)wParam, (const char *)lParam);
-
- return 0; // Failure
-}
-
-INT_PTR CIcqProto::SendYouWereAdded(WPARAM, LPARAM lParam)
-{
- if (lParam && icqOnline()) {
- CCSDATA* ccs = (CCSDATA*)lParam;
- if (ccs->hContact) {
- DWORD dwUin;
- if (getContactUid(ccs->hContact, &dwUin, nullptr))
- return 1; // Invalid contact
-
- DWORD dwMyUin = getContactUin(NULL);
- if (dwUin) {
- icq_sendYouWereAddedServ(dwUin, dwMyUin);
- return 0; // Success
- }
- }
- }
-
- return 1; // Failure
-}
-
-INT_PTR CIcqProto::SetMyAvatar(WPARAM, LPARAM lParam)
-{
- if (!m_bAvatarsEnabled || !m_bSsiEnabled)
- return -2;
-
- wchar_t *tszFile = (wchar_t*)lParam;
- if (tszFile) { // set file for avatar
- int dwPaFormat = ::ProtoGetAvatarFileFormat(tszFile);
- if (dwPaFormat != PA_FORMAT_XML) {
- // if it should be image, check if it is valid
- HBITMAP avt = Bitmap_Load(tszFile);
- if (!avt)
- return -1;
-
- DeleteObject(avt);
- }
-
- wchar_t tszMyFile[MAX_PATH + 1];
- GetFullAvatarFileName(0, nullptr, dwPaFormat, tszMyFile, MAX_PATH);
-
- // if not in our storage, copy
- if (mir_wstrcmp(tszFile, tszMyFile) && !CopyFile(tszFile, tszMyFile, FALSE)) {
- debugLogA("Failed to copy our avatar to local storage.");
- return -1;
- }
-
- BYTE *hash = calcMD5HashOfFile(tszMyFile);
- if (hash == nullptr)
- return -1;
-
- BYTE ihash[0x14];
- // upload hash to server
- ihash[0] = 0; //unknown
- ihash[1] = dwPaFormat == PA_FORMAT_XML ? AVATAR_HASH_FLASH : AVATAR_HASH_STATIC; //hash type
- ihash[2] = 1; //hash status
- ihash[3] = 0x10; //hash len
- memcpy((ihash + 4), hash, 0x10);
- updateServAvatarHash(ihash, 0x14);
-
- if (setSettingBlob(NULL, "AvatarHash", ihash, 0x14))
- debugLogA("Failed to save avatar hash.");
-
- wchar_t tmp[MAX_PATH];
- PathToRelativeW(tszMyFile, tmp);
- setWString(NULL, "AvatarFile", tmp);
- SAFE_FREE((void**)&hash);
- }
- else {
- // delete user avatar
- delSetting("AvatarFile");
- setSettingBlob(NULL, "AvatarHash", hashEmptyAvatar, 9);
- updateServAvatarHash(hashEmptyAvatar, 9); // set blank avatar
- }
- return 0;
-}
-
-INT_PTR CIcqProto::SetNickName(WPARAM wParam, LPARAM lParam)
-{
- if (!icqOnline())
- return 0; // failure
-
- if (wParam & SMNN_UNICODE)
- setWString("Nick", (WCHAR*)lParam);
- else
- setString("Nick", (char*)lParam);
-
- return ChangeInfoEx(CIXT_BASIC, 0);
-}
-
-// TODO: Adding needs some more work in general
-
-MCONTACT CIcqProto::AddToListByUIN(DWORD dwUin, DWORD dwFlags)
-{
- int bAdded;
- MCONTACT hContact = HContactFromUIN(dwUin, &bAdded);
- if (hContact == NULL) // Failure
- return NULL;
-
- if (!(dwFlags & PALF_TEMPORARY) && db_get_b(hContact, "CList", "NotOnList", 0)) {
- setContactHidden(hContact, 0);
- db_unset(hContact, "CList", "NotOnList");
- }
- return hContact; // Success
-}
-
-MCONTACT CIcqProto::AddToListByUID(const char *szUID, DWORD dwFlags)
-{
- int bAdded;
- MCONTACT hContact = HContactFromUID(0, szUID, &bAdded);
- if (hContact == 0)
- return 0; // Failure
-
- if (!(dwFlags & PALF_TEMPORARY) && db_get_b(hContact, "CList", "NotOnList", 0)) {
- setContactHidden(hContact, 0);
- db_unset(hContact, "CList", "NotOnList");
- }
-
- return hContact; // Success
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::ICQAddRecvEvent(MCONTACT hContact, WORD wType, PROTORECVEVENT* pre, size_t cbBlob, PBYTE pBlob, DWORD flags)
-{
- flags |= DBEF_UTF;
- if (pre->flags & PREF_CREATEREAD)
- flags |= DBEF_READ;
-
- if (hContact && db_get_b(hContact, "CList", "Hidden", 0)) {
- // if the contact was hidden, add to client-list if not in server-list authed
- if (!getWord(hContact, DBSETTING_SERVLIST_ID, 0) || getByte(hContact, "Auth", 0)) {
- DWORD dwUin;
- uid_str szUid;
- getContactUid(hContact, &dwUin, &szUid);
- icq_sendNewContact(dwUin, szUid); /// FIXME
- }
- }
-
- AddEvent(hContact, wType, pre->timestamp, flags, cbBlob, pBlob);
-}
-
-INT_PTR __cdecl CIcqProto::IcqAddCapability(WPARAM, LPARAM lParam)
-{
- ICQ_CUSTOMCAP *icqCustomCapIn = (ICQ_CUSTOMCAP*)lParam;
- ICQ_CUSTOMCAP *icqCustomCap = new ICQ_CUSTOMCAP;
- memcpy(icqCustomCap, icqCustomCapIn, sizeof(ICQ_CUSTOMCAP));
- CustomCapList.insert(icqCustomCap);
- return 0;
-}
-
-
-INT_PTR __cdecl CIcqProto::IcqCheckCapability(WPARAM hContact, LPARAM lParam)
-{
- int res = 0;
- DBVARIANT dbvariant;
- ICQ_CUSTOMCAP *icqCustomCap = (ICQ_CUSTOMCAP *)lParam;
-
- db_get(hContact, m_szModuleName, "CapBuf", &dbvariant);
- if (dbvariant.type == DBVT_BLOB)
- res = MatchCapability(dbvariant.pbVal, dbvariant.cpbVal, (const capstr*)&icqCustomCap->caps, 0x10) ? 1 : 0; // FIXME: Why icqCustomCap->caps is not capstr?
-
- db_free(&dbvariant);
- return res;
-}
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR icq_getEventTextMissedMessage(WPARAM pEvent, LPARAM datatype)
-{
- DBEVENTINFO *dbei = (DBEVENTINFO *)pEvent;
-
- INT_PTR nRetVal = 0;
- char *pszText = nullptr;
-
- if (dbei->cbBlob > 1) {
- switch (((WORD*)dbei->pBlob)[0]) {
- case 0:
- pszText = LPGEN("** This message was blocked by the ICQ server ** The message was invalid.");
- break;
-
- case 1:
- pszText = LPGEN("** This message was blocked by the ICQ server ** The message was too long.");
- break;
-
- case 2:
- pszText = LPGEN("** This message was blocked by the ICQ server ** The sender has flooded the server.");
- break;
-
- case 4:
- pszText = LPGEN("** This message was blocked by the ICQ server ** You are too evil.");
- break;
-
- default:
- pszText = LPGEN("** Unknown missed message event.");
- break;
- }
- if (datatype == DBVT_WCHAR) {
- int wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszText, (int)mir_strlen(pszText), nullptr, 0);
-
- WCHAR *pwszText = (WCHAR*)_alloca((wchars + 1) * sizeof(WCHAR));
- pwszText[wchars] = 0;
-
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszText, (int)mir_strlen(pszText), pwszText, wchars);
-
- nRetVal = (INT_PTR)mir_wstrdup(TranslateW(pwszText));
- }
- else if (datatype == DBVT_ASCIIZ)
- nRetVal = (INT_PTR)mir_strdup(Translate(pszText));
- }
-
- return nRetVal;
-}
diff --git a/protocols/IcqOscarJ/src/icqosc_svcs.h b/protocols/IcqOscarJ/src/icqosc_svcs.h
deleted file mode 100644
index 96ed6ca2ae..0000000000
--- a/protocols/IcqOscarJ/src/icqosc_svcs.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#ifndef __ICQOSC_SVCS_H
-#define __ICQOSC_SVCS_H
-
-
-#define ICQ_DB_GETEVENTTEXT_MISSEDMESSAGE "ICQ/GetEventTextMissedMessage"
-
-INT_PTR icq_getEventTextMissedMessage(WPARAM wParam, LPARAM lParam);
-
-
-#endif /* __ICQOSC_SVCS_H */
diff --git a/protocols/IcqOscarJ/src/init.cpp b/protocols/IcqOscarJ/src/init.cpp
deleted file mode 100644
index 5576337788..0000000000
--- a/protocols/IcqOscarJ/src/init.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-#include "m_extraicons.h"
-#include "m_icolib.h"
-
-BOOL bPopupService = FALSE;
-
-HANDLE hExtraXStatus;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static PLUGININFOEX pluginInfoEx = {
- sizeof(PLUGININFOEX),
- __PLUGIN_NAME,
- PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
- __DESCRIPTION,
- __AUTHOR,
- __COPYRIGHT,
- __AUTHORWEB,
- UNICODE_AWARE, //doesn't replace anything built-in
- { 0x73a9615c, 0x7d4e, 0x4555, { 0xba, 0xdb, 0xee, 0x5, 0xdc, 0x92, 0x8e, 0xff } } // {73A9615C-7D4E-4555-BADB-EE05DC928EFF}
-};
-
-CMPlugin::CMPlugin() :
- ACCPROTOPLUGIN<CIcqProto>(ICQ_PROTOCOL_NAME, pluginInfoEx)
-{
- SetUniqueId(UNIQUEIDSETTING);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOCOL, MIID_LAST };
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CMPlugin g_plugin;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int ModuleLoad(WPARAM, LPARAM)
-{
- bPopupService = ServiceExists(MS_POPUP_ADDPOPUPT);
- return 0;
-}
-
-IconItem iconList[] =
-{
- { LPGEN("Expand string edit"), "ICO_EXPANDSTRINGEDIT", IDI_EXPANDSTRINGEDIT }
-};
-
-int CMPlugin::Load()
-{
- srand(time(0));
- _tzset();
-
- // Initialize charset conversion routines
- InitI18N();
-
- // Register static services
- CreateServiceFunction(ICQ_DB_GETEVENTTEXT_MISSEDMESSAGE, icq_getEventTextMissedMessage);
-
- // Init extra statuses
- InitXStatusIcons();
- HookEvent(ME_SKIN2_ICONSCHANGED, OnReloadIcons);
-
- HookEvent(ME_SYSTEM_MODULELOAD, ModuleLoad);
- HookEvent(ME_SYSTEM_MODULEUNLOAD, ModuleLoad);
-
- hExtraXStatus = ExtraIcon_RegisterIcolib("xstatus", LPGEN("ICQ xStatus"), "icq_xstatus13");
-
- g_plugin.registerIcon("Protocols/ICQ", iconList);
-
- g_MenuInit();
- return 0;
-}
-
-int CMPlugin::Unload()
-{
- // destroying contact menu
- g_MenuUninit();
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// UpdateGlobalSettings event
-
-void CIcqProto::UpdateGlobalSettings()
-{
- char szServer[MAX_PATH] = "";
- getSettingStringStatic(NULL, "OscarServer", szServer, MAX_PATH);
-
- m_bSecureConnection = getByte("SecureConnection", DEFAULT_SECURE_CONNECTION);
- if (szServer[0]) {
- if (strstr(szServer, "aol.com"))
- setString("OscarServer", m_bSecureConnection ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST);
-
- if (m_bSecureConnection && !_strnicmp(szServer, "login.", 6)) {
- setString("OscarServer", DEFAULT_SERVER_HOST_SSL);
- setWord("OscarPort", DEFAULT_SERVER_PORT_SSL);
- }
- }
-
- if (m_hNetlibUser) {
- NETLIBUSERSETTINGS nlus = { sizeof(NETLIBUSERSETTINGS) };
- if (!m_bSecureConnection && Netlib_GetUserSettings(m_hNetlibUser, &nlus)) {
- if (nlus.useProxy && nlus.proxyType == PROXYTYPE_HTTP)
- m_bGatewayMode = 1;
- else
- m_bGatewayMode = 0;
- }
- else m_bGatewayMode = 0;
- }
-
- m_bSecureLogin = getByte("SecureLogin", DEFAULT_SECURE_LOGIN);
- m_bLegacyFix = getByte("LegacyFix", DEFAULT_LEGACY_FIX);
- m_wAnsiCodepage = getWord("AnsiCodePage", DEFAULT_ANSI_CODEPAGE);
- m_bDCMsgEnabled = getByte("DirectMessaging", DEFAULT_DCMSG_ENABLED);
- m_bTempVisListEnabled = getByte("TempVisListEnabled", DEFAULT_TEMPVIS_ENABLED);
- m_bSsiEnabled = getByte("UseServerCList", DEFAULT_SS_ENABLED);
- m_bSsiSimpleGroups = FALSE; /// TODO: enable, after server-list revolution is over
- m_bAvatarsEnabled = getByte("AvatarsEnabled", DEFAULT_AVATARS_ENABLED);
- m_bXStatusEnabled = getByte("XStatusEnabled", DEFAULT_XSTATUS_ENABLED);
- m_bMoodsEnabled = getByte("MoodsEnabled", DEFAULT_MOODS_ENABLED);
-}
diff --git a/protocols/IcqOscarJ/src/log.cpp b/protocols/IcqOscarJ/src/log.cpp
deleted file mode 100644
index 6639a7f796..0000000000
--- a/protocols/IcqOscarJ/src/log.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-extern BOOL bPopupService;
-
-static const char *szLevelDescr[] = { LPGEN("ICQ Note"), LPGEN("ICQ Warning"), LPGEN("ICQ Error"), LPGEN("ICQ Fatal") };
-
-struct LogMessageInfo
-{
- const char *szMsg;
- const char *szTitle;
- BYTE bLevel;
-};
-
-
-void __cdecl CIcqProto::icq_LogMessageThread(void* arg)
-{
- LogMessageInfo *err = (LogMessageInfo*)arg;
- if (!err)
- return;
- Thread_SetName("ICQ: LogMessageThread");
-
- if (bPopupService && getByte("PopupsLogEnabled", DEFAULT_LOG_POPUPS_ENABLED)) {
- ShowPopupMsg(NULL, err->szTitle, err->szMsg, err->bLevel);
-
- SAFE_FREE((void**)&err->szMsg);
- SAFE_FREE((void**)&err);
-
- return;
- }
-
- bErrorBoxVisible = TRUE;
- if (err->szMsg && err->szTitle)
- MessageBoxUtf(nullptr, err->szMsg, err->szTitle, MB_OK);
- SAFE_FREE((void**)&err->szMsg);
- SAFE_FREE((void**)&err);
- bErrorBoxVisible = FALSE;
-}
-
-
-void CIcqProto::icq_LogMessage(int level, const char *szMsg)
-{
- debugLogA("%s", szMsg);
-
- int displayLevel = getByte("ShowLogLevel", LOG_WARNING);
- if (level >= displayLevel) {
- if (!bErrorBoxVisible || !getByte("IgnoreMultiErrorBox", 0)) {
- // error not shown or allowed multi - show messagebox
- LogMessageInfo *lmi = (LogMessageInfo*)SAFE_MALLOC(sizeof(LogMessageInfo));
- lmi->bLevel = (BYTE)level;
- lmi->szMsg = null_strdup(szMsg);
- lmi->szTitle = szLevelDescr[level];
- ForkThread(&CIcqProto::icq_LogMessageThread, lmi);
- }
- }
-}
-
-void CIcqProto::icq_LogUsingErrorCode(int level, DWORD dwError, const char *szMsg)
-{
- char szBuf[1024];
- char str[1024];
- char str2[64];
- char szErrorMsg[512];
- char *pszErrorMsg = nullptr;
- int bNeedFree = FALSE;
-
- switch (dwError) {
- case ERROR_TIMEOUT:
- case WSAETIMEDOUT:
- pszErrorMsg = LPGEN("The server did not respond to the connection attempt within a reasonable time, it may be temporarily down. Try again later.");
- break;
-
- case ERROR_GEN_FAILURE:
- pszErrorMsg = LPGEN("The connection with the server was abortively closed during the connection attempt. You may have lost your local network connection.");
- break;
-
- case WSAEHOSTUNREACH:
- case WSAENETUNREACH:
- pszErrorMsg = LPGEN("Miranda was unable to resolve the name of a server to its numeric address. This is most likely caused by a catastrophic loss of your network connection (for example, your modem has disconnected), but if you are behind a proxy, you may need to use the 'Resolve hostnames through proxy' option in Options -> Network.");
- break;
-
- case WSAEHOSTDOWN:
- case WSAENETDOWN:
- case WSAECONNREFUSED:
- pszErrorMsg = LPGEN("Miranda was unable to make a connection with a server. It is likely that the server is down, in which case you should wait for a while and try again later.");
- break;
-
- case ERROR_ACCESS_DENIED:
- pszErrorMsg = LPGEN("Your proxy rejected the user name and password that you provided. Please check them in Options -> Network.");
- break;
-
- case WSAHOST_NOT_FOUND:
- case WSANO_DATA:
- pszErrorMsg = LPGEN("The server to which you are trying to connect does not exist. Check your spelling in Options -> Network -> ICQ.");
- break;
-
- default:
- wchar_t err[512];
- if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, dwError, 0, err, _countof(err), nullptr)) {
- pszErrorMsg = make_utf8_string(err);
- bNeedFree = TRUE;
- }
- break;
- }
-
- mir_snprintf(szBuf, "%s%s%s (%s %d)",
- szMsg ? ICQTranslateUtfStatic(szMsg, str, 1024) : "",
- szMsg ? "\r\n\r\n" : "",
- ICQTranslateUtfStatic(pszErrorMsg, szErrorMsg, 512),
- ICQTranslateUtfStatic(LPGEN("error"), str2, 64),
- dwError);
-
- if (bNeedFree)
- SAFE_FREE(&pszErrorMsg);
-
- icq_LogMessage(level, szBuf);
-}
-
-void CIcqProto::icq_LogFatalParam(const char *szMsg, WORD wError)
-{
- char str[MAX_PATH];
- char buf[MAX_PATH];
-
- mir_snprintf(buf, ICQTranslateUtfStatic(szMsg, str, _countof(str)), wError);
- icq_LogMessage(LOG_FATAL, buf);
-}
diff --git a/protocols/IcqOscarJ/src/log.h b/protocols/IcqOscarJ/src/log.h
deleted file mode 100644
index cc2223b0ca..0000000000
--- a/protocols/IcqOscarJ/src/log.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#ifndef __LOG_H
-#define __LOG_H
-
-#define LOG_NOTE 0 //trivial problems or problems that will already have been reported elsewhere
-#define LOG_WARNING 1 //problems that may have caused data loss
-#define LOG_ERROR 2 //problems that cause a disconnection from the network
-#define LOG_FATAL 3 //problems requiring user intervention: password wrong, rate exceeded, etc.
-
-#endif /* __LOG_H */
diff --git a/protocols/IcqOscarJ/src/loginpassword.cpp b/protocols/IcqOscarJ/src/loginpassword.cpp
deleted file mode 100644
index 6b897cf8de..0000000000
--- a/protocols/IcqOscarJ/src/loginpassword.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-INT_PTR CALLBACK LoginPasswdDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
-
- ppro = (CIcqProto*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
-
- Window_SetIcon_IcoLib(hwndDlg, ppro->m_hProtoIcon);
- {
- DWORD dwUin = ppro->getContactUin(NULL);
-
- wchar_t pszUIN[MAX_PATH];
- mir_snwprintf(pszUIN, TranslateT("Enter a password for UIN %u:"), dwUin);
- SetDlgItemText(hwndDlg, IDC_INSTRUCTION, pszUIN);
-
- SendDlgItemMessage(hwndDlg, IDC_LOGINPW, EM_LIMITTEXT, PASSWORDMAXLEN, 0);
-
- CheckDlgButton(hwndDlg, IDC_SAVEPASS, ppro->getByte("RememberPass", 0) ? BST_CHECKED : BST_UNCHECKED);
- }
- break;
-
- case WM_DESTROY:
- Window_FreeIcon_IcoLib(hwndDlg);
- break;
-
- case WM_CLOSE:
- EndDialog(hwndDlg, 0);
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDOK:
- ppro->m_bRememberPwd = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SAVEPASS);
- ppro->setByte("RememberPass", ppro->m_bRememberPwd);
-
- GetDlgItemTextA(hwndDlg, IDC_LOGINPW, ppro->m_szPassword, _countof(ppro->m_szPassword));
-
- ppro->icq_login(ppro->m_szPassword);
-
- EndDialog(hwndDlg, IDOK);
- break;
-
- case IDCANCEL:
- ppro->SetCurrentStatus(ID_STATUS_OFFLINE);
- EndDialog(hwndDlg, IDCANCEL);
- break;
- }
- break;
- }
-
- return FALSE;
-}
-
-void CIcqProto::RequestPassword()
-{
- DialogBoxParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_LOGINPW), nullptr, LoginPasswdDlgProc, LPARAM(this));
-}
diff --git a/protocols/IcqOscarJ/src/oscar_filetransfer.cpp b/protocols/IcqOscarJ/src/oscar_filetransfer.cpp
deleted file mode 100644
index 7065e8837b..0000000000
--- a/protocols/IcqOscarJ/src/oscar_filetransfer.cpp
+++ /dev/null
@@ -1,2116 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// OSCAR File-Transfers implementation
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-struct oscarthreadstartinfo
-{
- int type;
- int incoming;
- MCONTACT hContact;
- HNETLIBCONN hConnection;
- DWORD dwRemoteIP;
- oscar_filetransfer *ft;
- oscar_listener *listener;
-};
-
-// small utility function
-extern void NormalizeBackslash(char* path);
-
-//
-// Common functions
-/////////////////////////////
-
-char* FindFilePathContainer(const char **files, int iFile, char *szContainer)
-{
- const char *szThisFile = files[iFile];
- char *szFileName = (char*)ExtractFileName(szThisFile);
-
- szContainer[0] = '\0';
-
- if (szThisFile != szFileName) { // find an earlier subdirectory to be used as a container
- for (int i = iFile - 1; i >= 0; i--) {
- size_t len = mir_strlen(files[i]);
- if (!_strnicmp(files[i], szThisFile, len) && (szThisFile[len] == '\\' || szThisFile[len] == '/')) {
- const char *pszLastBackslash;
-
- if (((pszLastBackslash = strrchr(files[i], '\\')) == nullptr) &&
- ((pszLastBackslash = strrchr(files[i], '/')) == nullptr)) {
- mir_strcpy(szContainer, files[i]);
- }
- else {
- len = pszLastBackslash - files[i] + 1;
- null_strcpy(szContainer, szThisFile + len, szFileName - szThisFile - len);
- }
- }
- }
- }
- return szFileName;
-}
-
-//
-// Utility functions
-/////////////////////////////
-
-oscar_filetransfer* CIcqProto::CreateOscarTransfer()
-{
- oscar_filetransfer *ft = (oscar_filetransfer*)SAFE_MALLOC(sizeof(oscar_filetransfer));
- ft->ft_magic = FT_MAGIC_OSCAR; // Setup signature
- // Init members
- ft->fileId = -1;
- {
- mir_cslock l(oftMutex);
- m_arFileTransfers.insert(ft);
- }
-
- NetLog_Direct("OFT: FT struct %p created", ft);
- return ft;
-}
-
-filetransfer* CIcqProto::CreateIcqFileTransfer()
-{
- filetransfer *ft = (filetransfer*)SAFE_MALLOC(sizeof(filetransfer));
- ft->ft_magic = FT_MAGIC_ICQ;
- {
- mir_cslock l(oftMutex);
- m_arFileTransfers.insert(ft);
- }
-
- NetLog_Direct("FT struct %p created", ft);
- return ft;
-}
-
-int CIcqProto::IsValidFileTransfer(basic_filetransfer *ft)
-{
- mir_cslock l(oftMutex);
- return m_arFileTransfers.indexOf(ft) != -1;
-}
-
-int CIcqProto::IsValidOscarTransfer(basic_filetransfer *ft)
-{
- mir_cslock l(oftMutex);
- return m_arFileTransfers.indexOf(ft) != -1 && ft->ft_magic == FT_MAGIC_OSCAR;
-}
-
-oscar_filetransfer* CIcqProto::FindOscarTransfer(MCONTACT hContact, DWORD dwID1, DWORD dwID2)
-{
- mir_cslock l(oftMutex);
-
- for (auto &it : m_arFileTransfers) {
- if (it->ft_magic == FT_MAGIC_OSCAR) {
- oscar_filetransfer *oft = (oscar_filetransfer*)it;
- if (oft->hContact == hContact && oft->pMessage.dwMsgID1 == dwID1 && oft->pMessage.dwMsgID2 == dwID2)
- return oft;
- }
- }
-
- return nullptr;
-}
-
-// Release file transfer structure
-void CIcqProto::SafeReleaseFileTransfer(basic_filetransfer **bft)
-{
- mir_cslock l(oftMutex);
-
- // Check for filetransfer validity
- int idx = m_arFileTransfers.indexOf(*bft);
- if (idx == -1)
- return;
-
- if (*bft) {
- if ((*bft)->ft_magic == FT_MAGIC_ICQ) { // release ICQ filetransfer structure and its contents
- filetransfer *ift = (filetransfer*)(*bft);
-
- SAFE_FREE(&ift->szFilename);
- SAFE_FREE(&ift->szDescription);
- SAFE_FREE(&ift->szSavePath);
- SAFE_FREE(&ift->szThisSubdir);
- if (ift->pszFiles) {
- for (int i = 0; i < (int)ift->dwFileCount; i++) {
- // szThisFile can be a duplicate of pszFiles[i]
- if (ift->szThisFile == ift->pszFiles[i])
- ift->szThisFile = nullptr;
- SAFE_FREE(&ift->pszFiles[i]);
- }
- SAFE_FREE((void**)&ift->pszFiles);
- }
- SAFE_FREE(&ift->szThisFile);
- // Invalidate transfer
- m_arFileTransfers.remove(idx);
-
- NetLog_Direct("FT struct %p released", bft);
-
- // Release memory
- SAFE_FREE((void**)bft);
- }
- else if ((*bft)->ft_magic == FT_MAGIC_OSCAR) { // release oscar filetransfer structure and its contents
- oscar_filetransfer *oft = (oscar_filetransfer*)(*bft);
- // If connected, close connection
- if (oft->connection)
- CloseOscarConnection(oft->connection);
- // Release oscar listener
- if (oft->listener)
- ReleaseOscarListener((oscar_listener**)&oft->listener);
- // Release cookie
- if (oft->dwCookie)
- FreeCookie(oft->dwCookie);
- // Release all dynamic members
- SAFE_FREE(&oft->rawFileName);
- SAFE_FREE(&oft->szSavePath);
- SAFE_FREE(&oft->szThisFile);
- SAFE_FREE(&oft->szThisPath);
- SAFE_FREE(&oft->szDescription);
-
- if (oft->files) {
- for (int i = 0; i < oft->wFilesCount; i++)
- SAFE_FREE(&oft->files[i].szFile);
- SAFE_FREE((void**)&oft->files);
- }
-
- if (oft->files_list)
- SAFE_FREE((void**)&oft->files_list);
-
- if (oft->file_containers) {
- for (int i = 0; i < oft->containerCount; i++)
- SAFE_FREE(&oft->file_containers[i]);
- SAFE_FREE((void**)&oft->file_containers);
- }
-
- if (oft->fileId != -1)
- _close(oft->fileId);
-
- // Invalidate transfer
- m_arFileTransfers.remove(idx);
-
- NetLog_Direct("OFT: FT struct %p released", bft);
-
- // Release memory
- SAFE_FREE((void**)bft);
- }
- }
-}
-
-// Calculate oft checksum of buffer
-// --------------------------------
-// Information was gathered from Gaim's sources, thanks
-//
-DWORD oft_calc_checksum(int offset, const BYTE *buffer, int len, DWORD dwChecksum)
-{
- DWORD checksum = (dwChecksum >> 16) & 0xffff;
-
- for (int i = 0; i < len; i++) {
- WORD val = buffer[i];
-
- if (((i + offset) & 1) == 0)
- val = val << 8;
-
- if (checksum < val)
- checksum -= val + 1;
- else // simulate carry
- checksum -= val;
- }
- checksum = ((checksum & 0x0000ffff) + (checksum >> 16));
- checksum = ((checksum & 0x0000ffff) + (checksum >> 16));
- return checksum << 16;
-}
-
-DWORD oft_calc_file_checksum(int hFile, __int64 maxSize)
-{
- BYTE buf[OFT_BUFFER_SIZE];
- int bytesRead;
- __int64 offset = 0;
- DWORD dwCheck = 0xFFFF0000;
-
- _lseek(hFile, 0, SEEK_SET);
- bytesRead = _read(hFile, buf, (maxSize < sizeof(buf)) ? maxSize : (unsigned)sizeof(buf));
- if (bytesRead == -1)
- return dwCheck;
-
- while (bytesRead) {
- dwCheck = oft_calc_checksum((int)offset, buf, bytesRead, dwCheck);
- offset += bytesRead;
- bytesRead = _read(hFile, buf, sizeof(buf));
- if (bytesRead + offset > maxSize) bytesRead = (int)(maxSize - offset);
- }
- _lseek(hFile, 0, SEEK_SET); // back to beginning
-
- return dwCheck;
-}
-
-oscar_listener* CIcqProto::CreateOscarListener(oscar_filetransfer *ft, NETLIBNEWCONNECTIONPROC_V2 handler)
-{
- oscar_listener *listener = (oscar_listener*)SAFE_MALLOC(sizeof(oscar_listener));
- if (listener) {
- listener->ppro = this;
- listener->ft = ft;
- if (listener->hBoundPort = NetLib_BindPort(handler, listener, &listener->wPort, nullptr))
- return listener; // Success
-
- SAFE_FREE((void**)&listener);
- }
-
- return nullptr; // Failure
-}
-
-
-void CIcqProto::ReleaseOscarListener(oscar_listener **pListener)
-{
- oscar_listener *listener = *pListener;
- if (listener) { // Close listening port
- if (listener->hBoundPort) {
- Netlib_CloseHandle(listener->hBoundPort);
- listener->hBoundPort = nullptr;
- }
-
- NetLog_Direct("Oscar listener on port %d released.", listener->wPort);
- }
- SAFE_FREE((void**)pListener);
-}
-
-
-//
-// Miranda FT interface handlers & services
-/////////////////////////////
-
-void CIcqProto::handleRecvServMsgOFT(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwID1, DWORD dwID2, WORD wCommand)
-{
- MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr);
-
- if (wCommand == 0) { // this is OFT request
- oscar_tlv_chain* chain = readIntoTLVChain(&buf, wLen, 0);
-
- if (chain) {
- WORD wAckType = chain->getWord(0x0A, 1);
-
- if (wAckType == 1) { // This is first request in this OFT
- oscar_filetransfer *ft = CreateOscarTransfer();
- char *pszFileName = nullptr;
- char *pszDescription = nullptr;
-
- debugLogA("This is a file request");
-
- // This TLV chain may contain the following TLVs:
- // TLV(A): Acktype 0x0001 - file request / abort request
- // 0x0002 - file ack
- // TLV(F): Unknown
- // TLV(E): Language ?
- // TLV(2): Proxy IP
- // TLV(16): Proxy IP Check
- // TLV(3): External IP
- // TLV(4): Internal IP
- // TLV(5): Port
- // TLV(17): Port Check
- // TLV(10): Proxy Flag
- // TLV(D): Charset of User Message
- // TLV(C): User Message (ICQ_COOL_FT)
- // TLV(2711): FT info
- // TLV(2712): Charset of file name
-
- // init filetransfer structure
- ft->pMessage.dwMsgID1 = dwID1;
- ft->pMessage.dwMsgID2 = dwID2;
- ft->bUseProxy = chain->getTLV(0x10, 1) ? 1 : 0;
- ft->dwProxyIP = chain->getDWord(0x02, 1);
- ft->dwRemoteInternalIP = chain->getDWord(0x03, 1);
- ft->dwRemoteExternalIP = chain->getDWord(0x04, 1);
- ft->wRemotePort = chain->getWord(0x05, 1);
- ft->wReqNum = wAckType;
-
- { // User Message
- oscar_tlv* tlv = chain->getTLV(0x0C, 1);
-
- if (tlv) { // parse User Message
- BYTE* tBuf = tlv->pData;
-
- pszDescription = (char*)_alloca(tlv->wLen + 2);
- unpackString(&tBuf, (char*)pszDescription, tlv->wLen);
- pszDescription[tlv->wLen] = '\0';
- pszDescription[tlv->wLen + 1] = '\0';
- { // apply User Message encoding
- oscar_tlv *charset = chain->getTLV(0x0D, 1);
- char *str = pszDescription;
- char *bTag, *eTag;
-
- if (charset) { // decode charset
- char *szEnc = (char*)_alloca(charset->wLen + 1);
-
- null_strcpy(szEnc, (char*)charset->pData, charset->wLen);
- str = ApplyEncoding((char*)pszDescription, szEnc);
- }
- else str = null_strdup(str);
-
- // eliminate HTML tags
- pszDescription = EliminateHtml(str, mir_strlen(str));
-
- bTag = strstrnull(pszDescription, "<DESC>");
- if (bTag) { // take special Description - ICQJ's extension
- eTag = strstrnull(bTag, "</DESC>");
- if (eTag) {
- *eTag = '\0';
- str = null_strdup(bTag + 6);
- SAFE_FREE(&pszDescription);
- pszDescription = str;
- }
- }
- else {
- bTag = strstrnull(pszDescription, "<FS>");
- if (bTag) { // take only <FS> - Description tag if present
- eTag = strstrnull(bTag, "</FS>");
- if (eTag) {
- *eTag = '\0';
- str = null_strdup(bTag + 4);
- SAFE_FREE(&pszDescription);
- pszDescription = str;
- }
- }
- }
- }
- }
- if (!mir_strlen(pszDescription)) {
- SAFE_FREE(&pszDescription);
- pszDescription = ICQTranslateUtf(LPGEN("No description given"));
- }
- }
- { // parse File Transfer Info block
- oscar_tlv* tlv = chain->getTLV(0x2711, 1);
-
- // sanity check
- if (!tlv || tlv->wLen < 8) {
- debugLogA("Error: Malformed file request");
- // release structures
- SafeReleaseFileTransfer((basic_filetransfer**)&ft);
- SAFE_FREE(&pszDescription);
- return;
- }
-
- BYTE *tBuf = tlv->pData;
- size_t tLen = tlv->wLen;
- WORD wFlag;
-
- unpackWord(&tBuf, &wFlag); // FT flag
- unpackWord(&tBuf, &ft->wFilesCount);
- unpackDWord(&tBuf, (DWORD*)&ft->qwTotalSize);
- tLen -= 8;
- // Filename / Directory Name
- if (tLen) { // some filename specified, unpack
- size_t wFilenameLength = tLen - 1;
- pszFileName = (char*)_alloca(tLen);
- unpackString(&tBuf, (char*)pszFileName, wFilenameLength);
- pszFileName[wFilenameLength] = '\0';
- }
- else if (ft->wFilesCount == 1) // give some generic file name
- pszFileName = "unnamed_file";
- else // or empty directory name
- pszFileName = "";
-
- // apply Filename / Directory Name encoding
- oscar_tlv* charset = chain->getTLV(0x2712, 1);
- if (charset) {
- char* szEnc = (char*)_alloca(charset->wLen + 1);
- null_strcpy(szEnc, (char*)charset->pData, charset->wLen);
- pszFileName = ApplyEncoding(pszFileName, szEnc);
- }
- else pszFileName = ansi_to_utf8(pszFileName);
-
- if (ft->wFilesCount == 1) { // Filename - use for DB event
- char *szFileName = (char*)_alloca(mir_strlen(pszFileName) + 1);
-
- mir_strcpy(szFileName, pszFileName);
- SAFE_FREE(&pszFileName);
- pszFileName = szFileName;
- }
- else { // Save Directory name for future use
- ft->szThisPath = pszFileName;
- // for multi-file transfer we do not display "folder" name, but create only a simple notice
- pszFileName = (char*)_alloca(64);
-
- char tmp[64];
- mir_snprintf(pszFileName, 64, ICQTranslateUtfStatic(LPGEN("%d Files"), tmp, _countof(tmp)), ft->wFilesCount);
- }
- }
- // Total Size TLV (ICQ 6 and AIM 6)
- {
- oscar_tlv *tlv = chain->getTLV(0x2713, 1);
-
- if (tlv && tlv->wLen >= 8) {
- BYTE *tBuf = tlv->pData;
-
- unpackQWord(&tBuf, &ft->qwTotalSize);
- }
- }
- int bAdded;
- ft->hContact = HContactFromUID(dwUin, szUID, &bAdded);
- ft->fileId = -1;
-
- // Send chain event
- char *szBlob = (char*)_alloca(sizeof(DWORD) + mir_strlen(pszFileName) + mir_strlen(pszDescription) + 2);
- *(PDWORD)szBlob = 0;
- mir_strcpy(szBlob + sizeof(DWORD), pszFileName);
- mir_strcpy(szBlob + sizeof(DWORD) + mir_strlen(pszFileName) + 1, pszDescription);
-
- wchar_t* ptszFileName = mir_utf8decodeW(pszFileName);
-
- PROTORECVFILE pre = { 0 };
- pre.dwFlags = PRFF_UNICODE;
- pre.fileCount = 1;
- pre.timestamp = time(0);
- pre.descr.w = mir_utf8decodeW(pszDescription);
- pre.files.w = &ptszFileName;
- pre.lParam = (LPARAM)ft;
- ProtoChainRecvFile(ft->hContact, &pre);
-
- mir_free(pre.descr.w);
- mir_free(ptszFileName);
- }
- else if (wAckType == 2) { // First attempt failed, reverse requested
- oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2);
- if (ft) {
- NetLog_Direct("OFT: Redirect received (%d)", wAckType);
-
- ft->wReqNum = wAckType;
-
- if (ft->flags & OFTF_SENDING) {
- ReleaseOscarListener((oscar_listener**)&ft->listener);
-
- ft->bUseProxy = chain->getTLV(0x10, 1) ? 1 : 0;
- ft->dwProxyIP = chain->getDWord(0x02, 1);
- ft->dwRemoteInternalIP = chain->getDWord(0x03, 1);
- ft->dwRemoteExternalIP = chain->getDWord(0x04, 1);
- ft->wRemotePort = chain->getWord(0x05, 1);
-
- OpenOscarConnection(hContact, ft, ft->bUseProxy ? OCT_PROXY_RECV : OCT_REVERSE);
- }
- else { // Just sanity
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)ft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&ft);
- }
- }
- else debugLogA("Error: Invalid request, no such transfer");
- }
- else if (wAckType == 3) { // Transfering thru proxy, join tunnel
- oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2);
- if (ft) { // release possible previous listener
- NetLog_Direct("OFT: Redirect received (%d)", wAckType);
-
- ft->wReqNum = wAckType;
-
- ReleaseOscarListener((oscar_listener**)&ft->listener);
-
- ft->bUseProxy = chain->getTLV(0x10, 1) ? 1 : 0;
- ft->dwProxyIP = chain->getDWord(0x02, 1);
- ft->wRemotePort = chain->getWord(0x05, 1);
-
- if (ft->bUseProxy && ft->dwProxyIP) // Init proxy connection
- OpenOscarConnection(hContact, ft, OCT_PROXY_RECV);
- else // try Stage 4
- OpenOscarConnection(hContact, ft, OCT_PROXY);
- }
- else debugLogA("Error: Invalid request, no such transfer");
- }
- else if (wAckType == 4) {
- oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2);
- if (ft) {
- NetLog_Direct("OFT: Redirect received (%d)", wAckType);
-
- ft->wReqNum = wAckType;
- ft->bUseProxy = chain->getTLV(0x10, 1) ? 1 : 0;
- ft->dwProxyIP = chain->getDWord(0x02, 1);
- ft->wRemotePort = chain->getWord(0x05, 1);
-
- if (ft->bUseProxy && ft->dwProxyIP) // Init proxy connection
- OpenOscarConnection(hContact, ft, OCT_PROXY_RECV);
- else
- debugLogA("Error: Invalid request, IP missing.");
- }
- else debugLogA("Error: Invalid request, no such transfer");
- }
- else debugLogA("Error: Uknown Stage %d request", wAckType);
-
- disposeChain(&chain);
- }
- else debugLogA("Error: Missing TLV chain in OFT request");
- }
- else if (wCommand == 1) { // transfer cancelled/aborted
- oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2);
- if (ft) {
- debugLogA("OFT: File transfer cancelled by %s", strUID(dwUin, szUID));
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)ft, 0);
- // Notify user, that the FT was cancelled // TODO: new ACKRESULT_?
- icq_LogMessage(LOG_ERROR, LPGEN("The file transfer was aborted by the other user."));
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&ft);
- }
- else debugLogA("Error: Invalid request, no such transfer");
- }
- else if (wCommand == 2) { // transfer accepted - connection established
- oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2);
-
- if (ft) {
- NetLog_Direct("OFT: Session established.");
- // Init connection
- if (ft->flags & OFTF_SENDING) {
- if (ft->connection && ft->connection->status == OCS_CONNECTED) {
- if (!(ft->flags & OFTF_FILE_REQUEST_SENT)) {
- ft->flags |= OFTF_FILE_REQUEST_SENT;
- // proceed with first file
- oft_sendPeerInit(ft->connection);
- }
- }
- ft->flags |= OFTF_INITIALIZED; // accept was received
- }
- else debugLogA("Warning: Received invalid rendezvous accept");
- }
- else debugLogA("Error: Invalid request, no such transfer");
- }
- else debugLogA("Error: Unknown wCommand=0x%x in OFT request", wCommand);
-}
-
-void CIcqProto::handleRecvServResponseOFT(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, void* ft)
-{
- if (wLen < 2)
- return;
-
- size_t wDataLen;
- unpackWord(&buf, &wDataLen);
-
- if (wDataLen == 2) {
- oscar_filetransfer *oft = (oscar_filetransfer*)ft;
-
- WORD wStatus;
- unpackWord(&buf, &wStatus);
-
- switch (wStatus) {
- case 1:
- // FT denied (icq5)
- debugLogA("OFT: File transfer denied by %s", strUID(dwUin, szUID));
-
- ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)oft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oft);
- break;
-
- case 4: // Proxy error
- icq_LogMessage(LOG_ERROR, LPGEN("The file transfer failed: Proxy error"));
-
- ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oft);
- break;
-
- case 5: // Invalid request
- icq_LogMessage(LOG_ERROR, LPGEN("The file transfer failed: Invalid request"));
-
- ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oft);
- break;
-
- case 6: // Proxy Failed (IP = 0)
- icq_LogMessage(LOG_ERROR, LPGEN("The file transfer failed: Proxy unavailable"));
-
- ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oft);
- break;
-
- default:
- debugLogA("OFT: Uknown request response code 0x%x", wStatus);
-
- ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oft);
- }
- }
-}
-
-// This function is called from the Netlib when someone is connecting to our oscar_listener
-static void oft_newConnectionReceived(HNETLIBCONN hNewConnection, DWORD dwRemoteIP, void *pExtra)
-{
- oscarthreadstartinfo *otsi = (oscarthreadstartinfo*)SAFE_MALLOC(sizeof(oscarthreadstartinfo));
- oscar_listener *listener = (oscar_listener*)pExtra;
-
- otsi->type = listener->ft->flags & OFTF_SENDING ? OCT_NORMAL : OCT_REVERSE;
- otsi->incoming = 1;
- otsi->hConnection = hNewConnection;
- otsi->dwRemoteIP = dwRemoteIP;
- otsi->listener = listener;
-
- // Start a new thread for the incomming connection
- listener->ppro->ForkThread(&CIcqProto::oft_connectionThread, otsi);
-}
-
-static char* oftGetFileContainer(oscar_filetransfer* oft, const char** files, int iFile)
-{
- char szPath[MAX_PATH];
- FindFilePathContainer(files, iFile, szPath);
- char *szPathUtf = ansi_to_utf8(szPath);
- int i;
-
- // try to find existing container
- for (i = 0; i < oft->containerCount; i++)
- if (!mir_strcmp(szPathUtf, oft->file_containers[i])) {
- SAFE_FREE((void**)&szPathUtf);
- return oft->file_containers[i];
- }
-
- // create new container
- i = oft->containerCount++;
- oft->file_containers = (char**)SAFE_REALLOC(oft->file_containers, (sizeof(char*) * oft->containerCount));
- oft->file_containers[i] = szPathUtf;
-
- return oft->file_containers[i];
-}
-
-
-HANDLE CIcqProto::oftInitTransfer(MCONTACT hContact, DWORD dwUin, char* szUid, const wchar_t** files, const wchar_t* pszDesc)
-{
- int i, filesCount;
- struct _stati64 statbuf;
-
- // Initialize filetransfer struct
- debugLogA("Init file send");
-
- oscar_filetransfer *ft = CreateOscarTransfer();
- ft->hContact = hContact;
- ft->pMessage.bMessageType = MTYPE_FILEREQ;
- InitMessageCookie(&ft->pMessage);
-
- for (filesCount = 0; files[filesCount]; filesCount++);
- ft->files = (oft_file_record *)SAFE_MALLOC(sizeof(oft_file_record) * filesCount);
- ft->files_list = (char**)SAFE_MALLOC(sizeof(wchar_t *) * filesCount);
- ft->qwTotalSize = 0;
-
- char **filesUtf = (char**)SAFE_MALLOC(sizeof(char *) * filesCount);
- for (i = 0; i < filesCount; i++) filesUtf[i] = FileNameToUtf(files[i]);
-
- // Prepare files arrays
- for (i = 0; i < filesCount; i++) {
- if (_wstat64(files[i], &statbuf))
- debugLogA("IcqSendFile() was passed invalid filename \"%s\"", files[i]);
- else {
- if (!(statbuf.st_mode & _S_IFDIR)) { // take only files
- ft->files[ft->wFilesCount].szFile = ft->files_list[ft->wFilesCount] = null_strdup(filesUtf[i]);
- ft->files[ft->wFilesCount].szContainer = oftGetFileContainer(ft, (LPCSTR*)filesUtf, i);
-
- ft->wFilesCount++;
- ft->qwTotalSize += statbuf.st_size;
- }
- }
- }
-
- for (i = 0; i < filesCount; i++)
- SAFE_FREE(&filesUtf[i]);
- SAFE_FREE((void**)&filesUtf);
-
- if (!ft->wFilesCount) { // found no valid files to send
- icq_LogMessage(LOG_ERROR, LPGEN("Failed to Initialize File Transfer. No valid files were specified."));
- // Notify UI
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)ft, 0);
-
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&ft);
- return nullptr; // Failure
- }
-#ifdef __GNUC__
-#define OSCAR_MAX_SIZE 0x100000000ULL
-#else
-#define OSCAR_MAX_SIZE 0x100000000
-#endif
- if (ft->qwTotalSize >= OSCAR_MAX_SIZE && ft->wFilesCount > 1) { // file larger than 4GB can be send only as single
- icq_LogMessage(LOG_ERROR, LPGEN("The files are too big to be sent at once. Files bigger than 4 GB can be sent only separately."));
- // Notify UI
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)ft, 0);
-
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&ft);
- return nullptr; // Failure
- }
-
- debugLogA("OFT: Found %d files.", ft->wFilesCount);
-
- ft->szDescription = make_utf8_string(pszDesc);
- ft->flags = OFTF_SENDING;
- ft->fileId = -1;
- ft->iCurrentFile = 0;
- ft->dwCookie = AllocateCookie(CKT_FILE, ICQ_MSG_SRV_SEND, hContact, ft);
-
- // Init oscar fields
- {
- ft->wEncrypt = 0;
- ft->wCompress = 0;
- ft->wPartsCount = 1;
- ft->wPartsLeft = 1;
- mir_strcpy(ft->rawIDString, "Cool FileXfer");
- ft->bHeaderFlags = 0x20;
- ft->bNameOff = 0x1C;
- ft->bSizeOff = 0x11;
- ft->dwRecvForkCheck = 0xFFFF0000;
- ft->dwThisForkCheck = 0xFFFF0000;
- ft->dwRecvFileCheck = 0xFFFF0000;
- }
-
- // Send file transfer request
- {
- char *pszFiles;
-
- if (ft->wFilesCount == 1) { // transfering single file, give filename
- pszFiles = (char*)ExtractFileName(ft->files[0].szFile);
- }
- else { // check if transfering one directory
- char *szFirstDiv, *szFirstDir = ft->file_containers[0];
- size_t nFirstDirLen;
-
- // default is no root dir
- pszFiles = "";
-
- if ((szFirstDiv = strstrnull(szFirstDir, "\\")) || (szFirstDiv = strstrnull(szFirstDir, "/")))
- nFirstDirLen = szFirstDiv - szFirstDir;
- else
- nFirstDirLen = mir_strlen(szFirstDir);
-
- if (nFirstDirLen) { // got root dir from first container, check if others are only sub-dirs
- for (i = 0; i < ft->containerCount; i++) {
- if (_strnicmp((char*)ft->file_containers[i], (char*)szFirstDir, nFirstDirLen)) {
- szFirstDir = nullptr;
- break;
- }
- }
- if (szFirstDir) { // fine, we are sending only one directory
- pszFiles = szFirstDir;
- if (szFirstDiv) szFirstDiv[0] = '\0';
- nFirstDirLen++; // include backslash
- // cut all files container by root dir - it is transferred as root separately
- for (i = 0; i < ft->wFilesCount; i++)
- ft->files[i].szContainer += nFirstDirLen;
- }
- }
- }
-
- // Create listener
- ft->listener = CreateOscarListener(ft, oft_newConnectionReceived);
-
- // Send packet
- if (ft->listener) {
- oft_sendFileRequest(dwUin, szUid, ft, pszFiles, getDword("RealIP", 0));
- }
- else { // try stage 1 proxy
- ft->szThisFile = null_strdup(pszFiles);
- OpenOscarConnection(hContact, ft, OCT_PROXY_INIT);
- }
- }
-
- return ft; // Success
-}
-
-
-HANDLE CIcqProto::oftFileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szPath)
-{
- oscar_filetransfer *ft = (oscar_filetransfer*)hTransfer;
-
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return nullptr; // Invalid contact
-
- if (!IsValidOscarTransfer(ft))
- return nullptr; // Invalid transfer
-
- ft->szSavePath = make_utf8_string(szPath);
-
- if (ft->szThisPath) { // Append Directory name to the save path, when transfering a directory
- ft->szSavePath = (char*)SAFE_REALLOC(ft->szSavePath, mir_strlen(ft->szSavePath) + mir_strlen(ft->szThisPath) + 4);
- NormalizeBackslash(ft->szSavePath);
- mir_strcat(ft->szSavePath, ft->szThisPath);
- NormalizeBackslash(ft->szSavePath);
- }
-
- NetLog_Direct("OFT: Request accepted, saving to '%s'.", ft->szSavePath);
-
- // Create cookie
- ft->dwCookie = AllocateCookie(CKT_FILE, ICQ_MSG_SRV_SEND, hContact, ft);
-
- OpenOscarConnection(hContact, ft, ft->bUseProxy ? OCT_PROXY_RECV : OCT_NORMAL);
- return hTransfer; // Success
-}
-
-DWORD CIcqProto::oftFileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t*)
-{
- oscar_filetransfer *ft = (oscar_filetransfer*)hTransfer;
-
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return 1; // Invalid contact
-
- if (!IsValidOscarTransfer(ft))
- return 1; // Invalid transfer
-
- if (ft->hContact != hContact)
- return 1; // Bad contact or hTransfer
-
- NetLog_Direct("OFT: Request denied.");
-
- oft_sendFileDeny(dwUin, szUid, ft);
-
- // Release structure
- SafeReleaseFileTransfer((basic_filetransfer**)&ft);
- return 0; // Success
-}
-
-DWORD CIcqProto::oftFileCancel(MCONTACT hContact, HANDLE hTransfer)
-{
- oscar_filetransfer* ft = (oscar_filetransfer*)hTransfer;
-
- DWORD dwUin;
- uid_str szUid;
- if (getContactUid(hContact, &dwUin, &szUid))
- return 1; // Invalid contact
-
- if (!IsValidOscarTransfer(ft))
- return 1; // Invalid transfer
-
- if (ft->hContact != hContact)
- return 1; // Bad contact or hTransfer
-
- NetLog_Direct("OFT: Transfer cancelled.");
-
- oft_sendFileCancel(dwUin, szUid, ft);
-
- ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
-
- // Release structure
- SafeReleaseFileTransfer((basic_filetransfer**)&ft);
-
- return 0; // Success
-}
-
-void CIcqProto::oftFileResume(oscar_filetransfer *ft, int action, const wchar_t *szFilename)
-{
- int openFlags;
-
- if (ft->connection == nullptr)
- return;
-
- oscar_connection *oc = ft->connection;
-
- NetLog_Direct("OFT: Resume Transfer, Action: %d, FileName: '%s'", action, szFilename);
-
- switch (action) {
- case FILERESUME_RESUME:
- openFlags = _O_BINARY | _O_RDWR;
- break;
-
- case FILERESUME_OVERWRITE:
- openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY;
- ft->qwFileBytesDone = 0;
- break;
-
- case FILERESUME_SKIP:
- openFlags = _O_BINARY | _O_WRONLY;
- ft->qwFileBytesDone = ft->qwThisFileSize;
- break;
-
- case FILERESUME_RENAME:
- openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY;
- SAFE_FREE(&ft->szThisFile);
- ft->szThisFile = make_utf8_string(szFilename);
- ft->qwFileBytesDone = 0;
- break;
-
- default: // workaround for bug in Miranda Core
- if (ft->resumeAction == FILERESUME_RESUME)
- openFlags = _O_BINARY | _O_RDWR;
- else { // default to overwrite
- openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY;
- ft->qwFileBytesDone = 0;
- }
- }
- ft->resumeAction = action;
-
- ft->fileId = OpenFileUtf(ft->szThisFile, openFlags, _S_IREAD | _S_IWRITE);
- if (ft->fileId == -1) {
- NetLog_Direct("OFT: errno=%d", errno);
-
- icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder."));
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft);
- return;
- }
-
- if (action == FILERESUME_RESUME)
- ft->qwFileBytesDone = _lseeki64(ft->fileId, 0, SEEK_END);
- else
- _lseeki64(ft->fileId, ft->qwFileBytesDone, SEEK_SET);
-
- ft->qwBytesDone += ft->qwFileBytesDone;
-
- if (action == FILERESUME_RESUME) { // use smart-resume
- oc->status = OCS_RESUME;
- ft->dwRecvFileCheck = oft_calc_file_checksum(ft->fileId, ft->qwFileBytesDone);
- _lseek(ft->fileId, 0, SEEK_END);
-
- NetLog_Direct("OFT: Starting Smart-Resume");
-
- sendOFT2FramePacket(oc, OFT_TYPE_RESUMEREQUEST);
- return;
- }
-
- if (action == FILERESUME_SKIP) // we are skipping the file, send "we are done"
- oc->status = OCS_NEGOTIATION;
-
- else { // Send "we are ready"
- oc->status = OCS_DATA;
- ft->flags |= OFTF_FILE_RECEIVING;
-
- sendOFT2FramePacket(oc, OFT_TYPE_READY);
- }
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
-
- if (!ft->qwThisFileSize || action == FILERESUME_SKIP) { // if the file is empty we will not receive any data
- BYTE buf;
- oft_handleFileData(oc, &buf, 0);
- }
-}
-
-
-static void oft_buildProtoFileTransferStatus(oscar_filetransfer* ft, PROTOFILETRANSFERSTATUS* pfts)
-{
- memset(pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
- pfts->hContact = ft->hContact;
- pfts->flags = PFTS_UTF + ((ft->flags & OFTF_SENDING) ? PFTS_SENDING : PFTS_RECEIVING);
- if (ft->flags & OFTF_SENDING)
- pfts->pszFiles.a = ft->files_list;
- else
- pfts->pszFiles.a = nullptr; /* FIXME */
- pfts->totalFiles = ft->wFilesCount;
- pfts->currentFileNumber = ft->iCurrentFile;
- pfts->totalBytes = ft->qwTotalSize;
- pfts->totalProgress = ft->qwBytesDone;
- pfts->szWorkingDir.a = ft->szThisPath;
- pfts->szCurrentFile.a = ft->szThisFile;
- pfts->currentFileSize = ft->qwThisFileSize;
- pfts->currentFileTime = ft->dwThisFileDate;
- pfts->currentFileProgress = ft->qwFileBytesDone;
-}
-
-void CIcqProto::CloseOscarConnection(oscar_connection *oc)
-{
- mir_cslock l(oftMutex);
-
- if (oc) {
- oc->type = OCT_CLOSING;
- if (oc->hConnection) // we need this for Netlib handle consistency
- NetLib_CloseConnection(&oc->hConnection, FALSE);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OpenOscarConnection(MCONTACT hContact, oscar_filetransfer *ft, int type)
-{
- oscarthreadstartinfo *otsi = (oscarthreadstartinfo*)SAFE_MALLOC(sizeof(oscarthreadstartinfo));
-
- otsi->hContact = hContact;
- otsi->type = type;
- otsi->ft = ft;
-
- ForkThread((MyThreadFunc)&CIcqProto::oft_connectionThread, otsi);
-}
-
-int CIcqProto::CreateOscarProxyConnection(oscar_connection *oc)
-{
- // inform UI
- ProtoBroadcastAck(oc->ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTPROXY, oc->ft, 0);
-
- NETLIBOPENCONNECTION nloc = { 0 };
- nloc.szHost = OSCAR_PROXY_HOST;
- nloc.wPort = getWord("OscarPort", m_bSecureConnection ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT);
- if (nloc.wPort == 0)
- nloc.wPort = RandRange(1024, 65535);
- if (m_bGatewayMode)
- nloc.flags |= NLOCF_HTTPGATEWAY;
-
- oc->hConnection = NetLib_OpenConnection(m_hNetlibUser, "Proxy ", &nloc);
- if (!oc->hConnection) // proxy connection failed
- return 0;
-
- oc->type = OCT_PROXY;
- oc->status = OCS_PROXY;
- oc->ft->connection = oc;
-
- // init proxy
- proxy_sendInitTunnel(oc);
- return 1; // Success
-}
-
-void __cdecl CIcqProto::oft_connectionThread(void *param)
-{
- Thread_SetName("ICQ: oft_connectionThread");
-
- DWORD dwRemoteIP;
- oscar_connection oc = {};
- oscar_listener *source;
- {
- oscarthreadstartinfo *otsi = (oscarthreadstartinfo*)param;
- source = otsi->listener;
- dwRemoteIP = otsi->dwRemoteIP;
-
- oc.hContact = otsi->hContact;
- oc.hConnection = otsi->hConnection;
- oc.type = otsi->type;
- oc.incoming = otsi->incoming;
- oc.ft = otsi->ft;
- SAFE_FREE((void**)&otsi);
- }
-
- if (oc.incoming) {
- if (IsValidOscarTransfer(source->ft)) {
- oc.ft = source->ft;
- oc.ft->dwRemoteExternalIP = dwRemoteIP;
- oc.hContact = oc.ft->hContact;
- oc.ft->connection = &oc;
- oc.status = OCS_CONNECTED;
- }
- else { // FT is already over, kill listener
- NetLog_Direct("Received unexpected connection, closing.");
-
- CloseOscarConnection(&oc);
- ReleaseOscarListener(&source);
- return;
- }
- }
-
- if (oc.hContact) // Load contact information
- getContactUid(oc.hContact, &oc.dwUin, &oc.szUid);
-
- // Load local IP information
- oc.dwLocalExternalIP = getDword("IP", 0);
- oc.dwLocalInternalIP = getDword("RealIP", 0);
-
- if (!oc.incoming) { // create outgoing connection
- if (oc.type == OCT_NORMAL || oc.type == OCT_REVERSE) { // create outgoing connection to peer
- NETLIBOPENCONNECTION nloc = { 0 };
- IN_ADDR addr = { 0 }, addr2 = { 0 };
-
- if (oc.ft->dwRemoteExternalIP == oc.dwLocalExternalIP && oc.ft->dwRemoteInternalIP)
- addr.S_un.S_addr = htonl(oc.ft->dwRemoteInternalIP);
- else if (oc.ft->dwRemoteExternalIP) {
- addr.S_un.S_addr = htonl(oc.ft->dwRemoteExternalIP);
- // for different internal, try it also (for LANs with multiple external IP, VPNs, etc.)
- if (oc.ft->dwRemoteInternalIP != oc.ft->dwRemoteExternalIP)
- addr2.S_un.S_addr = htonl(oc.ft->dwRemoteInternalIP);
- }
- else // try LAN
- addr.S_un.S_addr = htonl(oc.ft->dwRemoteInternalIP);
-
- // Inform UI that we will attempt to connect
- ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, oc.ft, 0);
-
- if (!addr.S_un.S_addr && oc.type == OCT_NORMAL) { // IP to connect to is empty, request reverse
- oscar_listener* listener = CreateOscarListener(oc.ft, oft_newConnectionReceived);
-
- if (listener) { // we got listening port, fine send request
- oc.ft->listener = listener;
- // notify UI
- ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_LISTENING, oc.ft, 0);
-
- oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, oc.dwLocalInternalIP, listener->wPort, FALSE);
- return;
- }
- if (!CreateOscarProxyConnection(&oc)) { // normal connection failed, notify peer, wait for error or stage 3 proxy
- oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, 0, 0, FALSE);
- // stage 3 can follow
- return;
- }
- }
- else if (addr.S_un.S_addr && oc.ft->wRemotePort) {
- nloc.szHost = inet_ntoa(addr);
- nloc.wPort = oc.ft->wRemotePort;
- nloc.timeout = 8; // 8 secs to connect
- oc.hConnection = NetLib_OpenConnection(m_hDirectNetlibUser, oc.type == OCT_REVERSE ? "Reverse " : nullptr, &nloc);
- if (!oc.hConnection && addr2.S_un.S_addr) { // first address failed, try second one if available
- nloc.szHost = inet_ntoa(addr2);
- oc.hConnection = NetLib_OpenConnection(m_hDirectNetlibUser, oc.type == OCT_REVERSE ? "Reverse " : nullptr, &nloc);
- }
- if (!oc.hConnection) {
- if (oc.type == OCT_NORMAL) { // connection failed, try reverse
- oscar_listener* listener = CreateOscarListener(oc.ft, oft_newConnectionReceived);
-
- if (listener) { // we got listening port, fine send request
- oc.ft->listener = listener;
- // notify UI that we await connection
- ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_LISTENING, oc.ft, 0);
-
- oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, oc.dwLocalInternalIP, listener->wPort, FALSE);
- return;
- }
- }
- if (!CreateOscarProxyConnection(&oc)) { // proxy connection failed, notify peer, wait for error or stage 4 proxy
- oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, 0, 0, FALSE);
- // stage 3 or stage 4 can follow
- return;
- }
- }
- else {
- oc.status = OCS_CONNECTED;
- // ack normal connection
- oc.ft->connection = &oc;
- // acknowledge OFT - connection is ready
- oft_sendFileAccept(oc.dwUin, oc.szUid, oc.ft);
- // signal UI
- ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, oc.ft, 0);
- }
- }
- else { // try proxy, stage 3 (sending)
- if (!CreateOscarProxyConnection(&oc)) { // proxy connection failed, notify peer, wait for error or stage 4 proxy
- oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, 0, 0, FALSE);
- // stage 4 can follow
- return;
- }
- }
- }
- else if (oc.type == OCT_PROXY_RECV) { // stage 2 & stage 4
- if (oc.ft->dwProxyIP && oc.ft->wRemotePort) { // create proxy connection, join tunnel
- NETLIBOPENCONNECTION nloc = { 0 };
- IN_ADDR addr = { 0 };
-
- // inform UI that we will connect to file proxy
- ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTPROXY, oc.ft, 0);
-
- addr.S_un.S_addr = htonl(oc.ft->dwProxyIP);
- nloc.szHost = inet_ntoa(addr);
- nloc.wPort = getWord("OscarPort", m_bSecureConnection ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT);
- if (nloc.wPort == 0)
- nloc.wPort = RandRange(1024, 65535);
- if (m_bGatewayMode)
- nloc.flags |= NLOCF_HTTPGATEWAY;
- oc.hConnection = NetLib_OpenConnection(m_hNetlibUser, "Proxy ", &nloc);
- if (!oc.hConnection) { // proxy connection failed, we are out of possibilities
- ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0);
- // notify the other side, that we failed
- oft_sendFileResponse(oc.dwUin, oc.szUid, oc.ft, 0x04);
- // Release structure
- SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft);
- return;
- }
- oc.status = OCS_PROXY;
- oc.ft->connection = &oc;
- // Join proxy tunnel
- proxy_sendJoinTunnel(&oc, oc.ft->wRemotePort);
- }
- else // stage 2 failed (empty IP)
- { // try stage 3, or send response error 0x06
- if (!CreateOscarProxyConnection(&oc)) {
- oft_sendFileResponse(oc.dwUin, oc.szUid, oc.ft, 0x06);
- // notify UI
- ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0);
- // Release structure
- SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft);
- return;
- }
- }
- }
- else if (oc.type == OCT_PROXY) { // stage 4
- if (!CreateOscarProxyConnection(&oc)) { // proxy connection failed, we are out of possibilities
- ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0);
- // notify the other side, that we failed
- oft_sendFileResponse(oc.dwUin, oc.szUid, oc.ft, 0x06);
- // Release structure
- SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft);
- return;
- }
- }
- else if (oc.type == OCT_PROXY_INIT) { // stage 1
- if (!CreateOscarProxyConnection(&oc)) { // We failed to init transfer, notify UI
- icq_LogMessage(LOG_ERROR, LPGEN("Failed to Initialize File Transfer. Unable to bind local port and File proxy unavailable."));
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft);
- return;
- }
- else
- oc.type = OCT_PROXY_INIT;
- }
- }
-
- if (!oc.hConnection) { // one more sanity check
- NetLog_Direct("Error: No OFT connection.");
- return;
- }
-
- if (oc.status != OCS_PROXY) { // Connected, notify FT UI
- ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, oc.ft, 0);
-
- // send init OFT frame - just for different order of packets (just like Trillian)
- if (oc.status == OCS_CONNECTED && (oc.ft->flags & OFTF_SENDING) && ((oc.ft->flags & OFTF_INITIALIZED) || oc.type == OCT_REVERSE) && !(oc.ft->flags & OFTF_FILE_REQUEST_SENT)) {
- oc.ft->flags |= OFTF_FILE_REQUEST_SENT;
- // proceed with first file
- oft_sendPeerInit(&oc);
- }
- }
-
- HANDLE hPacketRecver = Netlib_CreatePacketReceiver(oc.hConnection, 8192);
- NETLIBPACKETRECVER packetRecv = {};
-
- // Packet receiving loop
-
- while (oc.hConnection) {
- packetRecv.dwTimeout = oc.wantIdleTime ? 0 : 120000;
-
- int recvResult = Netlib_GetMorePackets(hPacketRecver, &packetRecv);
- if (!recvResult) {
- NetLog_Direct("Clean closure of oscar socket (%p)", oc.hConnection);
- break;
- }
-
- if (recvResult == SOCKET_ERROR) {
- if (GetLastError() == ERROR_TIMEOUT) { // TODO: this will not work on some systems
- if (oc.wantIdleTime) { // here we want to send file data packets
- oft_sendFileData(&oc);
- }
- else if (oc.status != OCS_WAITING) {
- NetLog_Direct("Connection timeouted, closing.");
- break;
- }
- }
- else if (oc.type != OCT_CLOSING || GetLastError() != 87) { // log only significant errors, not "connection killed by us"
- NetLog_Direct("Abortive closure of oscar socket (%p) (%d)", oc.hConnection, GetLastError());
- break;
- }
- }
-
- if (oc.type == OCT_CLOSING)
- packetRecv.bytesUsed = packetRecv.bytesAvailable;
- else
- packetRecv.bytesUsed = oft_handlePackets(&oc, packetRecv.buffer, packetRecv.bytesAvailable);
- }
-
- // End of packet receiving loop
-
- NetLib_SafeCloseHandle(&hPacketRecver);
-
- CloseOscarConnection(&oc);
-
- // Clean up
- {
- mir_cslock l(oftMutex);
- if (m_arFileTransfers.indexOf(oc.ft) != -1)
- oc.ft->connection = nullptr; // release link
- }
- // Give server some time for abort/cancel to arrive
- SleepEx(1000, TRUE);
- // Error handling
- if (IsValidOscarTransfer(oc.ft)) {
- if (oc.status == OCS_DATA) {
- ProtoBroadcastAck(oc.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0);
-
- icq_LogMessage(LOG_ERROR, LPGEN("Connection lost during file transfer."));
- // Release structure
- SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft);
- }
- else if (oc.status == OCS_NEGOTIATION) {
- ProtoBroadcastAck(oc.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0);
-
- icq_LogMessage(LOG_ERROR, LPGEN("File transfer negotiation failed for unknown reason."));
- // Release structure
- SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft);
- }
- }
-}
-
-void CIcqProto::sendOscarPacket(oscar_connection *oc, icq_packet *packet)
-{
- if (oc->hConnection) {
- int nResult = Netlib_Send(oc->hConnection, (const char*)packet->pData, packet->wLen, 0);
- if (nResult == SOCKET_ERROR) {
- NetLog_Direct("Oscar %p socket error: %d, closing", oc->hConnection, GetLastError());
- CloseOscarConnection(oc);
- }
- }
-
- SAFE_FREE((void**)&packet->pData);
-}
-
-int CIcqProto::oft_handlePackets(oscar_connection *oc, BYTE *buf, size_t len)
-{
- size_t bytesUsed = 0;
-
- while (len > 0) {
- if (oc->status == OCS_DATA && (oc->ft->flags & OFTF_FILE_RECEIVING))
- return oft_handleFileData(oc, buf, len);
-
- if (oc->status == OCS_PROXY)
- return oft_handleProxyData(oc, buf, len);
-
- if (len < 6)
- break;
-
- BYTE *pBuf = buf;
- DWORD dwHead;
- unpackDWord(&pBuf, &dwHead);
- if (dwHead != 0x4F465432) { // bad packet
- NetLog_Direct("OFT: Received invalid packet (dwHead = 0x%x).", dwHead);
-
- CloseOscarConnection(oc);
- break;
- }
-
- size_t datalen;
- unpackWord(&pBuf, &datalen);
-
- if (len < datalen) // wait for whole packet
- break;
-
- WORD datatype;
- unpackWord(&pBuf, &datatype);
-#ifdef _DEBUG
- NetLog_Direct("OFT2: Type %u, Length %u bytes", datatype, datalen);
-#endif
- handleOFT2FramePacket(oc, datatype, pBuf, datalen - 8);
-
- /* Increase pointers so we can check for more data */
- buf += datalen;
- len -= datalen;
- bytesUsed += datalen;
- }
-
- return (int)bytesUsed;
-}
-
-int CIcqProto::oft_handleProxyData(oscar_connection *oc, BYTE *buf, size_t len)
-{
- oscar_filetransfer *ft = oc->ft;
- size_t datalen, bytesUsed = 0;
-
- while (len > 2) {
- BYTE *pBuf = buf;
-
- unpackWord(&pBuf, &datalen);
- datalen += 2;
-
- if (len < datalen)
- break; // packet is not complete
-
- if (datalen < 12) { // malformed packet
- CloseOscarConnection(oc);
- break;
- }
- pBuf += 2; // packet version
-
- WORD wCommand;
- unpackWord(&pBuf, &wCommand);
- pBuf += 6;
-
- // handle packet
- switch (wCommand) {
- case 0x01: // Error
- WORD wError;
- char* szError;
-
- unpackWord(&pBuf, &wError);
- switch (wError) {
- case 0x0D:
- szError = "Bad request";
- break;
- case 0x0E:
- szError = "Malformed packet";
- break;
- case 0x10:
- szError = "Initial request timeout";
- break;
- case 0x1A:
- szError = "Accept period timeout";
- break;
- case 0x1C:
- szError = "Invalid data";
- break;
-
- default:
- szError = "Unknown";
- }
- // Notify peer
- oft_sendFileResponse(oc->dwUin, oc->szUid, oc->ft, 0x06);
-
- debugLogA("Proxy Error: %s (0x%x)", szError, wError);
- // Notify UI
- ProtoBroadcastAck(oc->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc->ft, 0);
- // Release structure
- SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft);
- break;
-
- case 0x03: // Tunnel created
- WORD wCode;
- DWORD dwIP;
-
- unpackWord(&pBuf, &wCode);
- unpackDWord(&pBuf, &dwIP);
-
- if (oc->type == OCT_PROXY_INIT) { // Proxy ready, send Stage 1 Request
- ft->bUseProxy = 1;
- ft->wRemotePort = wCode;
- ft->dwProxyIP = dwIP;
- oft_sendFileRequest(oc->dwUin, oc->szUid, ft, ft->szThisFile, 0);
- SAFE_FREE(&ft->szThisFile);
- // Notify UI
- ProtoBroadcastAck(oc->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, oc->ft, 0);
- }
- else {
- debugLogA("Proxy Tunnel ready, notify peer.");
- oft_sendFileRedirect(oc->dwUin, oc->szUid, ft, dwIP, wCode, TRUE);
- }
- break;
-
- case 0x05: // Connection ready
- oc->status = OCS_CONNECTED; // connection ready to send packets
- // Notify UI
- ProtoBroadcastAck(oc->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, oc->ft, 0);
- // signal we are ready
- if (oc->type == OCT_PROXY_RECV) {
- oft_sendFileAccept(oc->dwUin, oc->szUid, ft);
- if (ft->flags & OFTF_SENDING) // connection is ready for transfer (sending only)
- ft->flags |= OFTF_INITIALIZED;
- }
-
- debugLogA("Proxy Tunnel established");
-
- if ((ft->flags & OFTF_INITIALIZED) && (ft->flags & OFTF_SENDING) && !(ft->flags & OFTF_FILE_REQUEST_SENT)) {
- ft->flags |= OFTF_FILE_REQUEST_SENT;
- // proceed with first file
- oft_sendPeerInit(ft->connection);
- }
- break;
-
- default:
- debugLogA("Unknown proxy command 0x%x", wCommand);
- }
-
- buf += datalen;
- len -= datalen;
- bytesUsed += datalen;
- }
-
- return (int)bytesUsed;
-}
-
-int CIcqProto::oft_handleFileData(oscar_connection *oc, BYTE *buf, size_t len)
-{
- oscar_filetransfer *ft = oc->ft;
- size_t dwLen = len, bytesUsed = 0;
-
- // do not accept more data than expected
- if (ft->qwThisFileSize - ft->qwFileBytesDone < dwLen)
- dwLen = (int)(ft->qwThisFileSize - ft->qwFileBytesDone);
-
- if (ft->fileId == -1) { // something went terribly bad
- CloseOscarConnection(oc);
- return 0;
- }
-
- _write(ft->fileId, buf, (unsigned)dwLen);
- // update checksum
- ft->dwRecvFileCheck = oft_calc_checksum((int)ft->qwFileBytesDone, buf, (unsigned)dwLen, ft->dwRecvFileCheck);
- bytesUsed += dwLen;
- ft->qwBytesDone += dwLen;
- ft->qwFileBytesDone += dwLen;
-
- // notify FT UI of our progress, at most every 700ms - do not be faster than Miranda
- if (GetTickCount() > ft->dwLastNotify + 700 || ft->qwFileBytesDone == ft->qwThisFileSize) {
- PROTOFILETRANSFERSTATUS pfts;
- oft_buildProtoFileTransferStatus(ft, &pfts);
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&pfts);
- ft->dwLastNotify = GetTickCount();
- }
-
- if (ft->qwFileBytesDone == ft->qwThisFileSize) {
- /* EOF */
- ft->flags &= ~OFTF_FILE_RECEIVING;
-
- _close(ft->fileId);
- ft->fileId = -1;
-
- if (ft->resumeAction != FILERESUME_SKIP && ft->dwRecvFileCheck != ft->dwThisFileCheck) {
- NetLog_Direct("Error: File checksums does not match!");
-
- // Notify UI
- char *pszMsg = ICQTranslateUtf(LPGEN("The checksum of file \"%s\" does not match, the file is probably damaged."));
- char szBuf[MAX_PATH];
-
- mir_snprintf(szBuf, pszMsg, ExtractFileName(ft->szThisFile));
- icq_LogMessage(LOG_ERROR, szBuf);
-
- SAFE_FREE(&pszMsg);
- }
- // keep transfer going (icq6 ignores checksums completely)
- else if (ft->resumeAction == FILERESUME_SKIP)
- NetLog_Direct("OFT: File receive skipped.");
- else
- NetLog_Direct("OFT: File received successfully.");
-
- if ((DWORD)(ft->iCurrentFile + 1) == ft->wFilesCount) {
- ft->bHeaderFlags = 0x01; // the whole process is over
- // ack received file
- sendOFT2FramePacket(oc, OFT_TYPE_DONE);
- oc->type = OCT_CLOSING;
- NetLog_Direct("File Transfer completed successfully.");
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&ft);
- }
- else { // ack received file
- sendOFT2FramePacket(oc, OFT_TYPE_DONE);
- oc->status = OCS_NEGOTIATION;
- }
- }
- return (int)bytesUsed;
-}
-
-void CIcqProto::handleOFT2FramePacket(oscar_connection *oc, WORD datatype, BYTE *pBuffer, size_t wLen)
-{
- oscar_filetransfer *ft = oc->ft;
- DWORD dwID1;
- DWORD dwID2;
-
- if (wLen < 232) { // allow shorter packets, but at least with filename
- NetLog_Direct("Error: Malformed OFT2 Frame, ignoring.");
- return;
- }
-
- unpackLEDWord(&pBuffer, &dwID1);
- wLen -= 4;
- unpackLEDWord(&pBuffer, &dwID2);
- wLen -= 4;
-
- if (datatype == OFT_TYPE_REQUEST && !(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) { // first request does not contain MsgIDs we need to send them in ready packet
- dwID1 = ft->pMessage.dwMsgID1;
- dwID2 = ft->pMessage.dwMsgID2;
- }
-
- if (ft->pMessage.dwMsgID1 != dwID1 || ft->pMessage.dwMsgID2 != dwID2) { // this is not the right packet - bad Message IDs
- NetLog_Direct("Error: Invalid Packet Cookie, closing.");
- CloseOscarConnection(oc);
- return;
- }
-
- switch (datatype) {
-
- case OFT_TYPE_REQUEST:
- // Sender ready
- if (ft->flags & OFTF_SENDING) { // just sanity check - this is only for receiving client
- NetLog_Direct("Error: Invalid Packet, closing.");
- CloseOscarConnection(oc);
- return;
- }
-
- // Read Frame data
- if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) {
- unpackWord(&pBuffer, &ft->wEncrypt);
- unpackWord(&pBuffer, &ft->wCompress);
- unpackWord(&pBuffer, &ft->wFilesCount);
- }
- else
- pBuffer += 6;
- unpackWord(&pBuffer, &ft->wFilesLeft);
- ft->iCurrentFile = ft->wFilesCount - ft->wFilesLeft;
- if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED))
- unpackWord(&pBuffer, &ft->wPartsCount);
- else
- pBuffer += 2;
- unpackWord(&pBuffer, &ft->wPartsLeft);
- if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) { // just check it
- DWORD dwSize;
-
- unpackDWord(&pBuffer, &dwSize);
- if (dwSize != (DWORD)ft->qwTotalSize) { // the 32bits does not match, use them as full size
- ft->qwTotalSize = dwSize;
- debugLogA("Warning: Invalid total size.");
- }
- }
- else pBuffer += 4;
-
- // this allows us to receive single >4GB file correctly
- DWORD dwSize;
- unpackDWord(&pBuffer, &dwSize);
- if (dwSize == (DWORD)ft->qwTotalSize && ft->wFilesCount == 1)
- ft->qwThisFileSize = ft->qwTotalSize;
- else
- ft->qwThisFileSize = dwSize;
-
- unpackDWord(&pBuffer, &ft->dwThisFileDate);
- unpackDWord(&pBuffer, &ft->dwThisFileCheck);
- unpackDWord(&pBuffer, &ft->dwRecvForkCheck);
- unpackDWord(&pBuffer, &ft->dwThisForkSize);
- unpackDWord(&pBuffer, &ft->dwThisFileCreation);
- unpackDWord(&pBuffer, &ft->dwThisForkCheck);
- pBuffer += 4; // File Bytes Done
- unpackDWord(&pBuffer, &ft->dwRecvFileCheck);
- if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED))
- unpackString(&pBuffer, ft->rawIDString, 32);
- else
- pBuffer += 32;
- unpackByte(&pBuffer, &ft->bHeaderFlags);
- unpackByte(&pBuffer, &ft->bNameOff);
- unpackByte(&pBuffer, &ft->bSizeOff);
- if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) {
- unpackString(&pBuffer, (char*)ft->rawDummy, 69);
- unpackString(&pBuffer, (char*)ft->rawMacInfo, 16);
- }
- else pBuffer += 85;
-
- unpackWord(&pBuffer, &ft->wEncoding);
- unpackWord(&pBuffer, &ft->wSubEncoding);
- ft->cbRawFileName = wLen - 176;
- SAFE_FREE((void**)&ft->rawFileName); // release previous buffers
- SAFE_FREE(&ft->szThisFile);
- ft->rawFileName = (char*)SAFE_MALLOC(ft->cbRawFileName + 2);
- unpackString(&pBuffer, ft->rawFileName, ft->cbRawFileName);
- // Prepare file
- if (ft->wEncoding == 2) // UCS-2 encoding
- ft->szThisFile = ApplyEncoding(ft->rawFileName, "unicode-2-0");
- else
- ft->szThisFile = ansi_to_utf8(ft->rawFileName);
-
- // convert dir markings to normal backslashes
- for (size_t i = 0; i < mir_strlen(ft->szThisFile); i++)
- if (ft->szThisFile[i] == 0x01)
- ft->szThisFile[i] = '\\';
-
- ft->flags |= OFTF_FILE_REQUEST_RECEIVED; // First Frame Processed
-
- NetLog_Direct("File '%s', %I64u Bytes", ft->szThisFile, ft->qwThisFileSize);
-
- { // Prepare Path Information
- char *szFile = strrchr(ft->szThisFile, '\\');
-
- SAFE_FREE(&ft->szThisPath); // release previous path
- if (szFile) {
- ft->szThisPath = ft->szThisFile;
- szFile[0] = '\0'; // split that strings
- ft->szThisFile = null_strdup(szFile + 1);
- // no cheating with paths
- if (!IsValidRelativePath(ft->szThisPath)) {
- NetLog_Direct("Invalid path information");
- break;
- }
- }
- else ft->szThisPath = null_strdup("");
- }
-
- /* no cheating with paths */
- if (!IsValidRelativePath(ft->szThisFile)) {
- NetLog_Direct("Invalid path information");
- break;
- }
-
- {
- char *szFullPath = (char*)SAFE_MALLOC(mir_strlen(ft->szSavePath) + mir_strlen(ft->szThisPath) + mir_strlen(ft->szThisFile) + 3);
- mir_strcpy(szFullPath, ft->szSavePath);
- NormalizeBackslash(szFullPath);
- mir_strcat(szFullPath, ft->szThisPath);
- NormalizeBackslash(szFullPath);
- // make sure the dest dir exists
- if (MakeDirUtf(szFullPath))
- NetLog_Direct("Failed to create destination directory!");
-
- mir_strcat(szFullPath, ft->szThisFile);
- // we joined the full path to dest file
- SAFE_FREE(&ft->szThisFile);
- ft->szThisFile = szFullPath;
- }
-
- ft->qwFileBytesDone = 0;
-
- /* file resume */
- PROTOFILETRANSFERSTATUS pfts;
- oft_buildProtoFileTransferStatus(ft, &pfts);
- if (ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, ft, (LPARAM)&pfts)) {
- oc->status = OCS_WAITING;
- break; /* UI supports resume: it will call PS_FILERESUME */
- }
-
- ft->fileId = OpenFileUtf(ft->szThisFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE);
-#ifdef _DEBUG
- NetLog_Direct("OFT: OpenFileUtf(%s, %u) returned %u", ft->szThisFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, ft->fileId);
-#endif
- if (ft->fileId == -1) {
-#ifdef _DEBUG
- NetLog_Direct("OFT: errno=%d", errno);
-#endif
- icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder."));
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft);
- return;
- }
-
- // Send "we are ready"
- oc->status = OCS_DATA;
- ft->flags |= OFTF_FILE_RECEIVING;
-
- sendOFT2FramePacket(oc, OFT_TYPE_READY);
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
- if (!ft->qwThisFileSize) { // if the file is empty we will not receive any data
- BYTE buf;
- oft_handleFileData(oc, &buf, 0);
- }
- return;
-
- case OFT_TYPE_READY:
- case OFT_TYPE_RESUMEACK:
- // Receiver is ready
- oc->status = OCS_DATA;
- oc->wantIdleTime = 1;
- ft->flags |= OFTF_FILE_SENDING;
-
- NetLog_Direct("OFT: Receiver ready.");
- break;
-
- case OFT_TYPE_RESUMEREQUEST:
- // Receiver wants to resume file transfer from point
- if (!(ft->flags & OFTF_SENDING)) { // just sanity check - this is only for sending client
- NetLog_Direct("Error: Invalid Packet, closing.");
- CloseOscarConnection(oc);
- return;
- }
-
- DWORD dwResumeCheck, dwResumeOffset, dwFileCheck;
- // Read Resume Frame data
- pBuffer += 44;
- unpackDWord(&pBuffer, &dwResumeOffset);
- unpackDWord(&pBuffer, &dwResumeCheck);
-
- dwFileCheck = oft_calc_file_checksum(ft->fileId, dwResumeOffset);
- if (dwFileCheck == dwResumeCheck && dwResumeOffset <= ft->qwThisFileSize) { // resume seems ok
- ft->qwFileBytesDone = dwResumeOffset;
- ft->qwBytesDone += dwResumeOffset;
- _lseek(ft->fileId, dwResumeOffset, SEEK_SET);
-
- NetLog_Direct("OFT: Resume request, ready.");
- }
- else
- NetLog_Direct("OFT: Resume request, restarting.");
-
- // Ready for resume
- sendOFT2FramePacket(oc, OFT_TYPE_RESUMEREADY);
- break;
-
- case OFT_TYPE_RESUMEREADY:
- // Process Smart-resume reply
- if (ft->flags & OFTF_SENDING) { // just sanity check - this is only for receiving client
- NetLog_Direct("Error: Invalid Packet, closing.");
- CloseOscarConnection(oc);
- return;
- }
-
- // Read Resume Reply data
- pBuffer += 44;
- unpackDWord(&pBuffer, &dwResumeOffset);
- unpackDWord(&pBuffer, &dwResumeCheck);
-
- if (ft->qwFileBytesDone != dwResumeOffset) {
- ft->qwBytesDone -= (ft->qwFileBytesDone - dwResumeOffset);
- ft->qwFileBytesDone = dwResumeOffset;
- if (dwResumeOffset)
- ft->dwRecvFileCheck = dwResumeCheck;
- else // Restarted resume (data mismatch)
- ft->dwRecvFileCheck = 0xFFFF0000;
- }
- _lseek(ft->fileId, dwResumeOffset, SEEK_SET);
-
- if (ft->qwThisFileSize != ft->qwFileBytesDone)
- NetLog_Direct("OFT: Resuming from offset %u.", dwResumeOffset);
-
- // Prepare to receive data
- oc->status = OCS_DATA;
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
-
- // Ready for receive
- sendOFT2FramePacket(oc, OFT_TYPE_RESUMEACK);
-
- if (ft->qwThisFileSize == ft->qwFileBytesDone) { // all data already processed
- BYTE buf;
-
- oft_handleFileData(oc, &buf, 0);
- }
- break;
-
- case OFT_TYPE_DONE:
- // File done
- oc->status = OCS_NEGOTIATION;
- oc->wantIdleTime = 0;
-
- ft->flags &= ~OFTF_FILE_SENDING;
-
- NetLog_Direct("OFT: File sent successfully.");
-
-#ifdef _DEBUG
- NetLog_Direct("OFT: _close(%u)", ft->fileId);
-#endif
- _close(ft->fileId); // FIXME: this needs fix for "skip file" feature
- ft->fileId = -1;
- ft->iCurrentFile++;
- // continue with next file
- oft_sendPeerInit(oc);
- break;
-
- default:
- NetLog_Direct("Error: Uknown OFT frame type 0x%x", datatype);
- }
-}
-
-//
-// Proxy packets
-/////////////////////////////
-
-void CIcqProto::proxy_sendInitTunnel(oscar_connection *oc)
-{
- icq_packet packet;
- size_t wLen = 39 + getUINLen(m_dwLocalUIN);
-
- packet.wLen = WORD(wLen);
- init_generic_packet(&packet, 2);
-
- packWord(&packet, WORD(wLen));
- packWord(&packet, OSCAR_PROXY_VERSION);
- packWord(&packet, 0x02); // wCommand
- packDWord(&packet, 0); // Unknown
- packWord(&packet, 0); // Flags?
- packUIN(&packet, m_dwLocalUIN);
- packLEDWord(&packet, oc->ft->pMessage.dwMsgID1);
- packLEDWord(&packet, oc->ft->pMessage.dwMsgID2);
- packDWord(&packet, 0x00010010); // TLV(1)
- packGUID(&packet, MCAP_FILE_TRANSFER);
-
- sendOscarPacket(oc, &packet);
-}
-
-void CIcqProto::proxy_sendJoinTunnel(oscar_connection *oc, WORD wPort)
-{
- icq_packet packet;
- size_t wLen = 41 + getUINLen(m_dwLocalUIN);
-
- packet.wLen = WORD(wLen);
- init_generic_packet(&packet, 2);
-
- packWord(&packet, WORD(wLen));
- packWord(&packet, OSCAR_PROXY_VERSION);
- packWord(&packet, 0x04); // wCommand
- packDWord(&packet, 0); // Unknown
- packWord(&packet, 0); // Flags?
- packUIN(&packet, m_dwLocalUIN);
- packWord(&packet, wPort);
- packLEDWord(&packet, oc->ft->pMessage.dwMsgID1);
- packLEDWord(&packet, oc->ft->pMessage.dwMsgID2);
- packDWord(&packet, 0x00010010); // TLV(1)
- packGUID(&packet, MCAP_FILE_TRANSFER);
-
- sendOscarPacket(oc, &packet);
-}
-
-//
-// Direct packets
-/////////////////////////////
-
-void CIcqProto::oft_sendFileData(oscar_connection *oc)
-{
- oscar_filetransfer *ft = oc->ft;
- BYTE buf[OFT_BUFFER_SIZE];
-
- if (ft->fileId == -1)
- return;
-
- int bytesRead = _read(ft->fileId, buf, sizeof(buf));
- if (bytesRead == -1)
- return;
-
- if (!bytesRead) { //
- oc->wantIdleTime = 0;
- return;
- }
-
- if ((DWORD)bytesRead > (ft->qwThisFileSize - ft->qwFileBytesDone)) { // do not send more than expected, limit to known size
- bytesRead = (DWORD)(ft->qwThisFileSize - ft->qwFileBytesDone);
- oc->wantIdleTime = 0;
- }
-
- if (bytesRead) {
- icq_packet packet;
- packet.wLen = bytesRead;
- init_generic_packet(&packet, 0);
- packBuffer(&packet, buf, bytesRead); // we are sending raw data
- sendOscarPacket(oc, &packet);
-
- ft->qwBytesDone += bytesRead;
- ft->qwFileBytesDone += bytesRead;
- }
-
- if (GetTickCount() > ft->dwLastNotify + 700 || oc->wantIdleTime == 0 || ft->qwFileBytesDone == ft->qwThisFileSize) { // notify only once a while or after last data packet sent
- PROTOFILETRANSFERSTATUS pfts;
- oft_buildProtoFileTransferStatus(ft, &pfts);
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&pfts);
- ft->dwLastNotify = GetTickCount();
- }
-}
-
-void CIcqProto::oft_sendPeerInit(oscar_connection *oc)
-{
- mir_cslock l(oftMutex);
-
- // prepare init frame
- oscar_filetransfer *ft = oc->ft;
- if (ft->iCurrentFile >= (int)ft->wFilesCount) { // All files done, great!
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft);
- return;
- }
-
- SAFE_FREE(&ft->szThisFile);
- ft->szThisFile = null_strdup(ft->files[ft->iCurrentFile].szFile);
-
- struct _stati64 statbuf;
- if (FileStatUtf(ft->szThisFile, &statbuf)) {
- icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it."));
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft);
- return;
- }
-
- // create full relative filename
- char* szThisContainer = ft->files[ft->iCurrentFile].szContainer;
-
- char *pszThisFileName = (char*)SAFE_MALLOC(mir_strlen(ft->szThisFile) + mir_strlen(szThisContainer) + 4);
- mir_strcpy(pszThisFileName, szThisContainer);
- NormalizeBackslash(pszThisFileName);
- mir_strcat(pszThisFileName, ExtractFileName(ft->szThisFile));
-
- // convert backslashes to dir markings
- for (size_t i = 0; i < mir_strlen(pszThisFileName); i++)
- if (pszThisFileName[i] == '\\' || pszThisFileName[i] == '/')
- pszThisFileName[i] = 0x01;
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
-
- ft->fileId = OpenFileUtf(ft->szThisFile, _O_BINARY | _O_RDONLY, 0);
- if (ft->fileId == -1) {
- NetLog_Direct("OFT: error opening file %s, errno=%d", ft->szThisFile, errno);
- SAFE_FREE((void**)&pszThisFileName);
- icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted (error=%d), because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it."));
-
- ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
- // Release transfer
- SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft);
- return;
- }
-
- ft->qwThisFileSize = statbuf.st_size;
- ft->dwThisFileDate = statbuf.st_mtime;
- ft->dwThisFileCreation = statbuf.st_ctime;
- ft->dwThisFileCheck = oft_calc_file_checksum(ft->fileId, ft->qwThisFileSize);
- ft->qwFileBytesDone = 0;
- ft->dwRecvFileCheck = 0xFFFF0000;
- SAFE_FREE((void**)&ft->rawFileName);
-
- if (IsUSASCII(pszThisFileName, mir_strlen(pszThisFileName))) {
- ft->wEncoding = 0; // ascii
- ft->cbRawFileName = WORD(mir_strlen(pszThisFileName) + 1);
- if (ft->cbRawFileName < 64)
- ft->cbRawFileName = 64;
- ft->rawFileName = (char*)SAFE_MALLOC(ft->cbRawFileName);
- mir_strcpy(ft->rawFileName, (char*)pszThisFileName);
- SAFE_FREE((void**)&pszThisFileName);
- }
- else {
- ft->wEncoding = 2; // ucs-2
- WCHAR *pwsThisFile = make_unicode_string(pszThisFileName);
- SAFE_FREE((void**)&pszThisFileName);
- ft->cbRawFileName = WORD(mir_wstrlen(pwsThisFile) * sizeof(WCHAR)) + 2;
- if (ft->cbRawFileName < 64)
- ft->cbRawFileName = 64;
- ft->rawFileName = (char*)SAFE_MALLOC(ft->cbRawFileName);
- // convert to LE ordered string
- BYTE *pwsThisFileBuf = (BYTE*)pwsThisFile; // need this - unpackWideString moves the address!
- unpackWideString(&pwsThisFileBuf, (WCHAR*)ft->rawFileName, mir_wstrlen(pwsThisFile) * sizeof(WCHAR));
- SAFE_FREE((void**)&pwsThisFile);
- }
- ft->wFilesLeft = WORD(ft->wFilesCount - ft->iCurrentFile);
-
- sendOFT2FramePacket(oc, OFT_TYPE_REQUEST);
-}
-
-void CIcqProto::sendOFT2FramePacket(oscar_connection *oc, WORD datatype)
-{
- oscar_filetransfer *ft = oc->ft;
-
- icq_packet packet;
- packet.wLen = WORD(192 + ft->cbRawFileName);
- init_generic_packet(&packet, 0);
-
- // Basic Oscar Frame
- packDWord(&packet, 0x4F465432); // Magic
- packWord(&packet, packet.wLen);
- packWord(&packet, datatype);
-
- // Cookie
- packLEDWord(&packet, ft->pMessage.dwMsgID1);
- packLEDWord(&packet, ft->pMessage.dwMsgID2);
- packWord(&packet, ft->wEncrypt);
- packWord(&packet, ft->wCompress);
- packWord(&packet, ft->wFilesCount);
- packWord(&packet, ft->wFilesLeft);
- packWord(&packet, ft->wPartsCount);
- packWord(&packet, ft->wPartsLeft);
- packDWord(&packet, (DWORD)ft->qwTotalSize);
- packDWord(&packet, (DWORD)ft->qwThisFileSize);
- packDWord(&packet, ft->dwThisFileDate);
- packDWord(&packet, ft->dwThisFileCheck);
- packDWord(&packet, ft->dwRecvForkCheck);
- packDWord(&packet, ft->dwThisForkSize);
- packDWord(&packet, ft->dwThisFileCreation);
- packDWord(&packet, ft->dwThisForkCheck);
- packDWord(&packet, (DWORD)ft->qwFileBytesDone);
- packDWord(&packet, ft->dwRecvFileCheck);
- packBuffer(&packet, (LPBYTE)ft->rawIDString, 32);
- packByte(&packet, ft->bHeaderFlags);
- packByte(&packet, ft->bNameOff);
- packByte(&packet, ft->bSizeOff);
- packBuffer(&packet, ft->rawDummy, 69);
- packBuffer(&packet, ft->rawMacInfo, 16);
- packWord(&packet, ft->wEncoding);
- packWord(&packet, ft->wSubEncoding);
- packBuffer(&packet, (LPBYTE)ft->rawFileName, ft->cbRawFileName);
-
- sendOscarPacket(oc, &packet);
-}
diff --git a/protocols/IcqOscarJ/src/oscar_filetransfer.h b/protocols/IcqOscarJ/src/oscar_filetransfer.h
deleted file mode 100644
index ad31c670a6..0000000000
--- a/protocols/IcqOscarJ/src/oscar_filetransfer.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// OSCAR File-Transfers headers
-// -----------------------------------------------------------------------------
-
-#ifndef __OSCAR_FILETRANSFER_H
-#define __OSCAR_FILETRANSFER_H
-
-#define FT_MAGIC_ICQ 0x00
-#define FT_MAGIC_OSCAR 0x4F
-
-struct basic_filetransfer
-{
- cookie_message_data pMessage;
- BYTE ft_magic;
- MCONTACT hContact;
- int iCurrentFile;
- DWORD dwCookie;
-};
-
-#define OFT_BUFFER_SIZE 8192
-
-struct oft_file_record
-{
- char *szContainer;
- char *szFile;
-};
-
-char *FindFilePathContainer(const char **files, int iFile, char *szContainer);
-
-
-// file-transfer status flags
-#define OFTF_INITIALIZED 0x0001 // connection established (ack received)
-#define OFTF_SENDING 0x0002 // sending files (receiving otherwise)
-#define OFTF_FILE_REQUEST_SENT 0x0004 // request sent (sending only)
-#define OFTF_FILE_REQUEST_RECEIVED 0x0008 // first request processed (receiving only)
-#define OFTF_FILE_SENDING 0x0010 // sending file contents
-#define OFTF_FILE_RECEIVING 0x0020 // receiving file contents
-#define OFTF_FILE_DONE 0x0040 // file finished
-
-struct oscar_filetransfer : public basic_filetransfer
-{
- int flags; // combination of OFTF_*
- int containerCount;
- char **file_containers;
- oft_file_record *files;
- char **files_list; // sending only
- int currentIsDir;
- int bUseProxy;
- DWORD dwProxyIP;
- DWORD dwRemoteInternalIP;
- DWORD dwRemoteExternalIP;
- WORD wRemotePort;
- char *szSavePath;
- char *szDescription;
- char *szThisFile;
- char *szThisPath;
- // Request sequence
- WORD wReqNum;
- // OFT2 header data
- WORD wEncrypt, wCompress;
- WORD wFilesCount, wFilesLeft;
- WORD wPartsCount, wPartsLeft;
- DWORD64 qwTotalSize;
- DWORD64 qwThisFileSize;
- DWORD dwThisFileDate; // modification date
- DWORD dwThisFileCheck;
- DWORD dwRecvForkCheck, dwThisForkSize;
- DWORD dwThisFileCreation; // creation date (not used)
- DWORD dwThisForkCheck;
- DWORD64 qwBytesDone;
- DWORD dwRecvFileCheck;
- char rawIDString[32];
- BYTE bHeaderFlags;
- BYTE bNameOff, bSizeOff;
- BYTE rawDummy[69];
- BYTE rawMacInfo[16];
- WORD wEncoding, wSubEncoding;
- size_t cbRawFileName;
- char *rawFileName;
- // helper data
- DWORD64 qwFileBytesDone;
- int fileId;
- struct oscar_connection *connection;
- struct oscar_listener *listener;
- DWORD dwLastNotify;
- int resumeAction;
-};
-
-#define OFT_TYPE_REQUEST 0x0101 // I am going to send you this file, is that ok?
-#define OFT_TYPE_READY 0x0202 // Yes, it is ok for you to send me that file
-#define OFT_TYPE_DONE 0x0204 // I received that file with no problems
-#define OFT_TYPE_RESUMEREQUEST 0x0205 // Resume transferring from position
-#define OFT_TYPE_RESUMEREADY 0x0106 // Ok, I am ready to send it
-#define OFT_TYPE_RESUMEACK 0x0207 // Fine, ready to receive
-
-struct oscar_connection
-{
- MCONTACT hContact;
- HNETLIBCONN hConnection;
- int status;
- DWORD dwUin;
- uid_str szUid;
- DWORD dwLocalInternalIP;
- DWORD dwLocalExternalIP;
- int type;
- int incoming;
- oscar_filetransfer *ft;
- int wantIdleTime;
-};
-
-#define OCT_NORMAL 0
-#define OCT_REVERSE 1
-#define OCT_PROXY 2
-#define OCT_PROXY_INIT 3
-#define OCT_PROXY_RECV 4
-#define OCT_CLOSING 10
-
-#define OCS_READY 0
-#define OCS_CONNECTED 1
-#define OCS_NEGOTIATION 2
-#define OCS_RESUME 3
-#define OCS_DATA 4
-#define OCS_PROXY 8
-#define OCS_WAITING 10
-
-struct oscar_listener
-{
- CIcqProto *ppro;
- WORD wPort;
- HNETLIBBIND hBoundPort;
- oscar_filetransfer *ft;
-};
-
-#endif /* __OSCAR_FILETRANSFER_H */
-
diff --git a/protocols/IcqOscarJ/src/resource.h b/protocols/IcqOscarJ/src/resource.h
deleted file mode 100644
index 2c7145236b..0000000000
--- a/protocols/IcqOscarJ/src/resource.h
+++ /dev/null
@@ -1,168 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by D:\miranda-ng\protocols\IcqOscarJ\res\resources.rc
-//
-#define IDS_IDENTIFY 102
-#define IDD_ICQACCOUNT 103
-#define IDD_ASKAUTH 104
-#define IDD_LOGINPW 105
-#define IDD_OPT_ICQ 108
-#define IDD_OPT_ICQCONTACTS 109
-#define IDD_OPT_ICQFEATURES 110
-#define IDD_OPT_ICQPRIVACY 111
-#define IDD_INFO_ICQ 240
-#define IDD_ICQADVANCEDSEARCH 242
-#define IDD_ICQUPLOADLIST 253
-#define IDD_SETXSTATUS 256
-#define IDD_PWCONFIRM 300
-#define IDD_INFO_CHANGEINFO 301
-#define IDD_OPT_POPUPS 400
-#define IDC_POPUPS_ENABLED 410
-#define IDC_POPUPS_LOG_ENABLED 411
-#define IDC_POPUPS_SPAM_ENABLED 412
-#define IDC_POPUP_LOG0_TEXTCOLOR 420
-#define IDC_POPUP_LOG1_TEXTCOLOR 421
-#define IDC_POPUP_LOG2_TEXTCOLOR 422
-#define IDC_POPUP_LOG3_TEXTCOLOR 423
-#define IDC_POPUP_SPAM_TEXTCOLOR 425
-#define IDC_POPUP_LOG0_BACKCOLOR 430
-#define IDC_POPUP_LOG1_BACKCOLOR 431
-#define IDC_POPUP_LOG2_BACKCOLOR 432
-#define IDC_POPUP_LOG3_BACKCOLOR 433
-#define IDC_POPUP_SPAM_BACKCOLOR 435
-#define IDC_POPUP_LOG0_TIMEOUT 440
-#define IDC_POPUP_LOG1_TIMEOUT 441
-#define IDC_POPUP_LOG2_TIMEOUT 442
-#define IDC_POPUP_LOG3_TIMEOUT 443
-#define IDC_POPUP_SPAM_TIMEOUT 444
-#define IDC_USEWINCOLORS 450
-#define IDC_USESYSICONS 451
-#define IDC_PREVIEW 455
-#define IDC_LOG 1001
-#define IDI_EXPANDSTRINGEDIT 1001
-#define IDC_SAVEPASS 1004
-#define IDC_RETRXSTATUS 1005
-#define IDC_XTITLE_STATIC 1006
-#define IDC_XMSG_STATIC 1007
-#define IDC_SSL 1008
-#define IDC_MD5LOGIN 1009
-#define IDC_XTITLE 1010
-#define IDC_LEGACY 1010
-#define IDC_KEEPALIVE 1011
-#define IDC_XMSG 1011
-#define IDC_UTFSTATIC 1013
-#define IDC_UTFCODEPAGE 1014
-#define IDC_PW 1015
-#define IDC_TEMPVISIBLE 1015
-#define IDC_REGISTER 1016
-#define IDC_EDITAUTH 1017
-#define IDC_LOGINPW 1018
-#define IDC_INSTRUCTION 1019
-#define IDC_PASSWORD 1020
-#define IDC_SUPTIME 1020
-#define IDC_DCENABLE 1020
-#define IDC_DCPASSIVE 1021
-#define IDC_OLDPASS 1021
-#define IDC_ICQNUM 1022
-#define IDC_USEPOPUPCOLORS 1023
-#define IDC_USEDEFCOLORS 1024
-#define IDC_CLIST 1035
-#define IDC_XSTATUSENABLE 1040
-#define IDC_XSTATUSAUTO 1041
-#define IDC_XSTATUSRESET 1042
-#define IDC_MOODSENABLE 1043
-#define IDC_KILLSPAMBOTS 1045
-#define IDC_EMAIL 1048
-#define IDC_NICK 1053
-#define IDC_GENDER 1060
-#define IDC_CITY 1061
-#define IDC_STATE 1062
-#define IDC_COUNTRY 1063
-#define IDC_COMPANY 1066
-#define IDC_DEPARTMENT 1067
-#define IDC_POSITION 1069
-#define IDC_IP 1094
-#define IDC_UINSTATIC 1122
-#define IDC_UIN 1123
-#define IDC_STATIC11 1154
-#define IDC_STATIC12 1155
-#define IDC_ICQSERVER 1171
-#define IDC_ICQPORT 1172
-#define IDC_VERSION 1179
-#define IDC_FIRSTNAME 1224
-#define IDC_LASTNAME 1225
-#define IDC_REALIP 1230
-#define IDC_RECONNECTREQD 1239
-#define IDC_OFFLINETOENABLE 1240
-#define IDC_PORT 1249
-#define IDC_MIRVER 1251
-#define IDC_ONLINESINCE 1252
-#define IDC_SYSTEMUPTIME 1253
-#define IDC_IDLETIME 1254
-#define IDC_STATUS 1255
-#define IDC_SLOWSEND 1301
-#define IDC_LOGLEVEL 1331
-#define IDC_LEVELDESCR 1332
-#define IDC_NOERRMULTI 1333
-#define IDC_STICQGROUP 1374
-#define IDC_AGERANGE 1410
-#define IDC_MARITALSTATUS 1411
-#define IDC_KEYWORDS 1412
-#define IDC_LANGUAGE 1414
-#define IDC_WORKFIELD 1421
-#define IDC_PASTCAT 1422
-#define IDC_PASTKEY 1423
-#define IDC_INTERESTSCAT 1424
-#define IDC_INTERESTSKEY 1425
-#define IDC_ORGANISATION 1426
-#define IDC_ORGKEYWORDS 1427
-#define IDC_OTHERGROUP 1429
-#define IDC_ONLINEONLY 1430
-#define IDC_HOMEPAGECAT 1431
-#define IDC_HOMEPAGEKEY 1432
-#define IDC_SUMMARYGROUP 1434
-#define IDC_WORKGROUP 1435
-#define IDC_LOCATIONGROUP 1436
-#define IDC_BACKGROUNDGROUP 1437
-#define IDC_NEWUINLINK 1438
-#define IDC_LOOKUPLINK 1439
-#define IDC_RESETSERVER 1472
-#define IDC_UPLOADNOW 1521
-#define IDC_GROUPS 1522
-#define IDC_ALLGROUPS 1526
-#define IDC_VISIBILITY 1527
-#define IDC_IGNORE 1528
-#define IDC_ENABLE 1529
-#define IDC_LOADFROMSERVER 1530
-#define IDC_ADDSERVER 1532
-#define IDC_SAVETOSERVER 1533
-#define IDC_ENABLEAVATARS 1536
-#define IDC_AUTOLOADAVATARS 1537
-#define IDC_STRICTAVATARCHECK 1539
-#define IDC_WEBAWARE 1546
-#define IDC_DCALLOW_ANY 1547
-#define IDC_DCALLOW_CLIST 1548
-#define IDC_DCALLOW_AUTH 1549
-#define IDC_PUBLISHPRIMARY 1550
-#define IDC_ADD_ANY 1551
-#define IDC_ADD_AUTH 1552
-#define IDC_STATUSMSG_CLIST 1553
-#define IDC_STATUSMSG_VISIBLE 1554
-#define IDC_STATIC_NOTONLINE 1555
-#define IDC_STATIC_DC2 1556
-#define IDC_STATIC_DC1 1557
-#define IDC_STATIC_CLIST 1558
-#define IDC_SAVE 1600
-#define IDC_LIST 1601
-#define IDC_UPLOADING 1602
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 113
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1026
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
diff --git a/protocols/IcqOscarJ/src/stdafx.cxx b/protocols/IcqOscarJ/src/stdafx.cxx
deleted file mode 100644
index 6ef3c8471b..0000000000
--- a/protocols/IcqOscarJ/src/stdafx.cxx
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-Copyright (C) 2012-18 Miranda NG team (https://miranda-ng.org)
-
-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 version 2
-of the License.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "stdafx.h"
diff --git a/protocols/IcqOscarJ/src/stdafx.h b/protocols/IcqOscarJ/src/stdafx.h
deleted file mode 100644
index 54f1712620..0000000000
--- a/protocols/IcqOscarJ/src/stdafx.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Includes all header files that should be precompiled to speed up compilation.
-// -----------------------------------------------------------------------------
-
-#pragma once
-
-// Windows includes
-#include <windows.h>
-#include <commctrl.h>
-
-// Standard includes
-#include <stdio.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <io.h>
-#include <malloc.h>
-#include <direct.h>
-#include <fcntl.h>
-#include <process.h>
-
-#ifndef _DEBUG
-#include <crtdbg.h>
-#endif
-
-#ifndef AW_VER_POSITIVE
-#define AW_VER_POSITIVE 0x00000004
-#endif
-
-#ifndef _ASSERTE
-#define _ASSERTE(x)
-#endif
-
-// Miranda IM SDK includes
-#include <newpluginapi.h> // This must be included first
-#include <m_clist.h>
-#include <m_database.h>
-#include <m_langpack.h>
-#include <m_message.h>
-#include <m_netlib.h>
-#include <m_protocols.h>
-#include <m_protosvc.h>
-#include <m_options.h>
-#include <m_system.h>
-#include <m_userinfo.h>
-#include <m_utils.h>
-#include <m_idle.h>
-#include <m_skin.h>
-#include <m_popup.h>
-#include <m_cluiframes.h>
-#include <m_ignore.h>
-#include <m_icolib.h>
-#include <m_avatars.h>
-#include <m_xstatus.h>
-#include <m_timezones.h>
-#include <win2k.h>
-#include <m_gui.h>
-
-// Project resources
-#include "resource.h"
-
-// ICQ plugin includes
-#include "version.h"
-#include "globals.h"
-#include "i18n.h"
-#include "cookies.h"
-#include "icq_packet.h"
-#include "utilities.h"
-#include "oscar_filetransfer.h"
-#include "icq_direct.h"
-#include "icq_server.h"
-#include "icqosc_svcs.h"
-#include "icq_servlist.h"
-#include "icq_http.h"
-#include "icq_fieldnames.h"
-#include "icq_constants.h"
-#include "capabilities.h"
-#include "guids.h"
-#include "stdpackets.h"
-#include "tlv.h"
-#include "channels.h"
-#include "families.h"
-#include "m_icq.h"
-#include "icq_advsearch.h"
-#include "log.h"
-
-#include "icq_rates.h"
-
-#include "icq_avatar.h"
-
-#include "changeinfo.h"
-#include "icq_popups.h"
-#include "icq_proto.h"
-
-extern IconItem iconList[]; \ No newline at end of file
diff --git a/protocols/IcqOscarJ/src/stdpackets.cpp b/protocols/IcqOscarJ/src/stdpackets.cpp
deleted file mode 100644
index 0888bd524d..0000000000
--- a/protocols/IcqOscarJ/src/stdpackets.cpp
+++ /dev/null
@@ -1,1798 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-extern const int moodXStatus[];
-
-/*****************************************************************************
-*
-* Some handy extra pack functions for basic message type headers
-*
-*/
-
-// This is the part of the message header that is common for all message channels
-static void packServMsgSendHeader(icq_packet *p, DWORD dwSequence, DWORD dwID1, DWORD dwID2, DWORD dwUin, const char *szUID, WORD wFmt, size_t wLen)
-{
- serverPacketInit(p, 21 + getUIDLen(dwUin, szUID) + wLen);
- packFNACHeader(p, ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, 0, dwSequence | ICQ_MSG_SRV_SEND << 0x10);
- packLEDWord(p, dwID1); // Msg ID part 1
- packLEDWord(p, dwID2); // Msg ID part 2
- packWord(p, wFmt); // Message channel
- packUID(p, dwUin, szUID); // User ID
-}
-
-static void packServIcqExtensionHeader(icq_packet *p, CIcqProto *ppro, size_t wLen, WORD wType, WORD wSeq, WORD wCmd = ICQ_META_CLI_REQUEST)
-{
- serverPacketInit(p, 24 + wLen);
- packFNACHeader(p, ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST, 0, wSeq | (wCmd << 0x10));
- packWord(p, 0x01); // TLV type 1
- packWord(p, WORD(10 + wLen)); // TLV len
- packLEWord(p, WORD(8 + wLen)); // Data chunk size (TLV.Length-2)
- packLEDWord(p, ppro->m_dwLocalUIN); // My UIN
- packLEWord(p, wType); // Request type
- packWord(p, wSeq);
-}
-
-static void packServIcqDirectoryHeader(icq_packet *p, CIcqProto *ppro, size_t wLen, WORD wType, WORD wCommand, WORD wSeq, WORD wSubCommand = ICQ_META_CLI_REQUEST)
-{
- packServIcqExtensionHeader(p, ppro, wLen + 0x1E, CLI_META_INFO_REQ, wSeq, wSubCommand);
- packLEWord(p, wType);
- packLEWord(p, WORD(wLen + 0x1A));
- packFNACHeader(p, 0x5b9, wCommand, 0, 0, 2);
- packWord(p, 0);
- packWord(p, (WORD)GetACP());
- packDWord(p, 2);
-}
-
-static void packServTLV5HeaderBasic(icq_packet *p, size_t wLen, DWORD ID1, DWORD ID2, WORD wCommand, const plugin_guid pGuid)
-{
- // TLV(5) header
- packWord(p, 0x05); // Type
- packWord(p, WORD(26 + wLen)); // Len
- // TLV(5) data
- packWord(p, wCommand); // Command
- packLEDWord(p, ID1); // msgid1
- packLEDWord(p, ID2); // msgid2
- packGUID(p, pGuid); // capabilities (4 dwords)
-}
-
-static void packServTLV5HeaderMsg(icq_packet *p, size_t wLen, DWORD ID1, DWORD ID2, WORD wAckType)
-{
- packServTLV5HeaderBasic(p, wLen + 10, ID1, ID2, 0, MCAP_SRV_RELAY_FMT);
-
- packTLVWord(p, 0x0A, wAckType); // TLV: 0x0A Acktype: 1 for normal, 2 for ack
- packDWord(p, 0x000F0000); // TLV: 0x0F empty
-}
-
-static void packServTLV2711Header(icq_packet *packet, WORD wCookie, WORD wVersion, BYTE bMsgType, BYTE bMsgFlags, WORD X1, WORD X2, size_t nLen)
-{
- packWord(packet, 0x2711); // Type
- packWord(packet, WORD(51 + nLen)); // Len
- // TLV(0x2711) data
- packLEWord(packet, 0x1B); // Unknown
- packByte(packet, (BYTE)wVersion); // Client (message) version
- packGUID(packet, PSIG_MESSAGE);
- packDWord(packet, CLIENTFEATURES);
- packDWord(packet, DC_TYPE);
- packLEWord(packet, wCookie); // Reference cookie
- packLEWord(packet, 0x0E); // Unknown
- packLEWord(packet, wCookie); // Reference cookie again
- packDWord(packet, 0); // Unknown (12 bytes)
- packDWord(packet, 0); // -
- packDWord(packet, 0); // -
- packByte(packet, bMsgType); // Message type
- packByte(packet, bMsgFlags); // Flags
- packLEWord(packet, X1); // Accepted
- packWord(packet, X2); // Unknown, priority?
-}
-
-static void packServDCInfo(icq_packet *p, CIcqProto* ppro, BOOL bEmpty)
-{
- packTLVDWord(p, 0x03, bEmpty ? 0 : ppro->getDword("RealIP", 0)); // TLV: 0x03 DWORD IP
- packTLVWord(p, 0x05, WORD(bEmpty ? 0 : ppro->wListenPort)); // TLV: 0x05 Listen port
-}
-
-static void packServChannel2Header(icq_packet *p, CIcqProto* ppro, DWORD dwUin, size_t wLen, DWORD dwID1, DWORD dwID2, DWORD dwCookie, WORD wVersion, BYTE bMsgType, BYTE bMsgFlags, WORD wPriority, int isAck, int includeDcInfo, BYTE bRequestServerAck)
-{
- packServMsgSendHeader(p, dwCookie, dwID1, dwID2, dwUin, nullptr, 0x0002, wLen + 95 + (bRequestServerAck ? 4 : 0) + (includeDcInfo ? 14 : 0));
-
- packWord(p, 0x05); // TLV type
- packWord(p, WORD(wLen + 91 + (includeDcInfo ? 14 : 0))); /* TLV len */
- packWord(p, WORD(isAck ? 2 : 0)); /* not aborting anything */
- packLEDWord(p, dwID1); // Msg ID part 1
- packLEDWord(p, dwID2); // Msg ID part 2
- packGUID(p, MCAP_SRV_RELAY_FMT); /* capability (4 dwords) */
- packDWord(p, 0x000A0002); // TLV: 0x0A WORD: 1 for normal, 2 for ack
- packWord(p, isAck ? 2 : 1);
-
- if (includeDcInfo)
- packServDCInfo(p, ppro, FALSE);
-
- packDWord(p, 0x000F0000); // TLV: 0x0F empty
-
- packServTLV2711Header(p, (WORD)dwCookie, wVersion, bMsgType, bMsgFlags, (WORD)MirandaStatusToIcq(ppro->m_iStatus), wPriority, wLen);
-}
-
-static void packServAdvancedReply(icq_packet *p, DWORD dwUin, const char *szUid, DWORD dwID1, DWORD dwID2, WORD wCookie, size_t wLen)
-{
- serverPacketInit(p, getUIDLen(dwUin, szUid) + 23 + wLen);
- packFNACHeader(p, ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE, 0, ICQ_MSG_RESPONSE << 0x10 | (wCookie & 0x7FFF));
- packLEDWord(p, dwID1); // Msg ID part 1
- packLEDWord(p, dwID2); // Msg ID part 2
- packWord(p, 0x02); // Channel
- packUID(p, dwUin, szUid); // Contact UID
- packWord(p, 0x03); // Msg specific formating
-}
-
-static void packServAdvancedMsgReply(icq_packet *p, DWORD dwUin, const char *szUid, DWORD dwID1, DWORD dwID2, WORD wCookie, WORD wVersion, BYTE bMsgType, BYTE bMsgFlags, size_t wLen)
-{
- packServAdvancedReply(p, dwUin, szUid, dwID1, dwID2, wCookie, wLen + 51);
-
- packLEWord(p, 0x1B); // Unknown
- packByte(p, (BYTE)wVersion); // Protocol version
- packGUID(p, PSIG_MESSAGE);
- packDWord(p, CLIENTFEATURES);
- packDWord(p, DC_TYPE);
- packLEWord(p, wCookie); // Reference
- packLEWord(p, 0x0E); // Unknown
- packLEWord(p, wCookie); // Reference
- packDWord(p, 0); // Unknown
- packDWord(p, 0); // Unknown
- packDWord(p, 0); // Unknown
- packByte(p, bMsgType); // Message type
- packByte(p, bMsgFlags); // Message flags
- packLEWord(p, 0); // Ack status code ( 0 = accepted, this is hardcoded because
- // it is only used this way yet)
- packLEWord(p, 0); // Unused priority field
-}
-
-void packMsgColorInfo(icq_packet *packet)
-{ // TODO: make configurable
- packLEDWord(packet, 0x00000000); // Foreground colour
- packLEDWord(packet, 0x00FFFFFF); // Background colour
-}
-
-void packEmptyMsg(icq_packet *packet)
-{
- packLEWord(packet, 1);
- packByte(packet, 0);
-}
-
-/*****************************************************************************
-*
-* Functions to actually send the stuff
-*
-*/
-
-void CIcqProto::icq_sendCloseConnection()
-{
- icq_packet packet;
-
- packet.wLen = 0;
- write_flap(&packet, ICQ_CLOSE_CHAN);
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_requestnewfamily(WORD wFamily, void (CIcqProto::*familyhandler)(HNETLIBCONN hConn, char* cookie, size_t cookieLen))
-{
- int bRequestSSL = m_bSecureConnection && (wFamily != ICQ_AVATAR_FAMILY); // Avatar servers does not support SSL
-
- cookie_family_request *request = (cookie_family_request*)SAFE_MALLOC(sizeof(cookie_family_request));
- request->wFamily = wFamily;
- request->familyHandler = familyhandler;
-
- DWORD dwCookie = AllocateCookie(CKT_SERVICEREQUEST, ICQ_CLIENT_NEW_SERVICE, 0, request); // generate and alloc cookie
-
- icq_packet packet;
- serverPacketInit(&packet, 12 + (bRequestSSL ? 4 : 0));
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_NEW_SERVICE, 0, dwCookie);
- packWord(&packet, wFamily);
- if (bRequestSSL)
- packDWord(&packet, 0x008C0000); // use SSL
-
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_setidle(bool bIsIdle)
-{
- // if mode isn't changed, don't spam the server
- if (bIsIdle == m_bIdleMode) {
- debugLogA("ICQ: idle mode wasn't changed (%d)", bIsIdle);
- return;
- }
-
- /* SNAC 1,11 */
- debugLogA("ICQ: set idle %d", bIsIdle);
- icq_packet packet;
- serverPacketInit(&packet, 14);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_IDLE);
- if (bIsIdle)
- packDWord(&packet, 0x0000003C);
- else
- packDWord(&packet, 0x00000000);
-
- m_bIdleMode = bIsIdle;
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_setstatus(WORD wStatus, const char *szStatusNote)
-{
- char *szCurrentStatusNote = szStatusNote ? getSettingStringUtf(NULL, DBSETTING_STATUS_NOTE, nullptr) : nullptr;
- size_t wStatusMoodLen = 0, wStatusNoteLen = 0, wSessionDataLen = 0;
- char *szMoodData = nullptr;
-
- if (szStatusNote && mir_strcmp(szCurrentStatusNote, szStatusNote)) { // status note was changed, update now
- DBVARIANT dbv = { DBVT_DELETED };
- if (m_bMoodsEnabled && !getString(DBSETTING_STATUS_MOOD, &dbv))
- szMoodData = null_strdup(dbv.pszVal);
-
- db_free(&dbv);
-
- wStatusNoteLen = mir_strlen(szStatusNote);
- wStatusMoodLen = mir_strlen(szMoodData);
-
- wSessionDataLen = (wStatusNoteLen ? wStatusNoteLen + 4 : 0) + 4 + wStatusMoodLen + 4;
- }
- SAFE_FREE(&szCurrentStatusNote);
-
- // Pack data in packet
- icq_packet packet;
- serverPacketInit(&packet, 18 + (wSessionDataLen ? wSessionDataLen + 4 : 0));
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS);
- packWord(&packet, 0x06); // TLV 6
- packWord(&packet, 0x04); // TLV length
- packWord(&packet, GetMyStatusFlags()); // Status flags
- packWord(&packet, wStatus); // Status
- if (wSessionDataLen) {
- packWord(&packet, 0x1D); // TLV 1D
- packWord(&packet, WORD(wSessionDataLen)); // TLV length
- packWord(&packet, 0x02); // Item Type
- if (wStatusNoteLen) {
- packWord(&packet, 0x400 | (WORD)(wStatusNoteLen + 4)); // Flags + Item Length
- packWord(&packet, WORD(wStatusNoteLen)); // Text Length
- packBuffer(&packet, (LPBYTE)szStatusNote, wStatusNoteLen);
- packWord(&packet, 0); // Encoding not specified (utf-8 is default)
- }
- else packWord(&packet, 0); // Flags + Item Length
-
- packWord(&packet, 0x0E); // Item Type
- packWord(&packet, WORD(wStatusMoodLen)); // Flags + Item Length
- if (wStatusMoodLen)
- packBuffer(&packet, (LPBYTE)szMoodData, wStatusMoodLen); // Mood
-
- // Save current status note
- db_set_utf(NULL, m_szModuleName, DBSETTING_STATUS_NOTE, szStatusNote);
- }
- // Release memory
- SAFE_FREE(&szMoodData);
-
- // Send packet
- sendServPacket(&packet);
-}
-
-DWORD CIcqProto::icq_SendChannel1Message(DWORD dwUin, char *szUID, MCONTACT hContact, char *pszText, cookie_message_data *pCookieData)
-{
- size_t wMessageLen = mir_strlen(pszText);
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
- size_t wPacketLength = (pCookieData->nAckType == ACKTYPE_SERVER) ? 25 : 21;
-
- // Pack the standard header
- icq_packet packet;
- packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, szUID, 1, wPacketLength + wMessageLen);
-
- // Pack first TLV
- packWord(&packet, 0x0002); // TLV(2)
- packWord(&packet, WORD(wMessageLen + 13)); // TLV len
-
- // Pack client features
- packWord(&packet, 0x0501); // TLV(501)
- packWord(&packet, 0x0001); // TLV len
- packByte(&packet, 0x1); // Features, meaning unknown, duplicated from ICQ Lite
-
- // Pack text TLV
- packWord(&packet, 0x0101); // TLV(2)
- packWord(&packet, WORD(wMessageLen + 4)); // TLV len
- packWord(&packet, 0x0003); // Message charset number, again copied from ICQ Lite
- packWord(&packet, 0x0000); // Message charset subset
- packBuffer(&packet, (LPBYTE)pszText, wMessageLen); // Message text
-
- // Pack request server ack TLV
- if (pCookieData->nAckType == ACKTYPE_SERVER)
- packDWord(&packet, 0x00030000); // TLV(3)
-
- // Pack store on server TLV
- packDWord(&packet, 0x00060000); // TLV(6)
-
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-
-DWORD CIcqProto::icq_SendChannel1MessageW(DWORD dwUin, char *szUID, MCONTACT hContact, WCHAR *pszText, cookie_message_data *pCookieData)
-{
- WORD wMessageLen = WORD(mir_wstrlen(pszText) * sizeof(WCHAR));
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
-
- WORD wPacketLength = (pCookieData->nAckType == ACKTYPE_SERVER) ? 26 : 22;
-
- // Pack the standard header
- icq_packet packet;
- packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, szUID, 1, wPacketLength + wMessageLen);
-
- // Pack first TLV
- packWord(&packet, 0x0002); // TLV(2)
- packWord(&packet, WORD(wMessageLen + 14)); // TLV len
-
- // Pack client features
- packWord(&packet, 0x0501); // TLV(501)
- packWord(&packet, 0x0002); // TLV len
- packWord(&packet, 0x0106); // Features, meaning unknown, duplicated from ICQ 2003b
-
- // Pack text TLV
- packWord(&packet, 0x0101); // TLV(2)
- packWord(&packet, WORD(wMessageLen + 4)); // TLV len
- packWord(&packet, 0x0002); // Message charset number, again copied from ICQ 2003b
- packWord(&packet, 0x0000); // Message charset subset
- WCHAR *ppText = pszText; // we must convert the widestring
- for (int i = 0; i < wMessageLen; i += 2, ppText++)
- packWord(&packet, *ppText);
-
- // Pack request server ack TLV
- if (pCookieData->nAckType == ACKTYPE_SERVER)
- packDWord(&packet, 0x00030000); // TLV(3)
-
- // Pack store on server TLV
- packDWord(&packet, 0x00060000); // TLV(6)
-
- sendServPacket(&packet);
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_SendChannel2Message(DWORD dwUin, MCONTACT hContact, const char *szMessage, size_t nBodyLen, WORD wPriority, cookie_message_data *pCookieData, char *szCap)
-{
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
-
- // Pack the standard header
- icq_packet packet;
- packServChannel2Header(&packet, this, dwUin, nBodyLen + (szCap ? 53 : 11), pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwCookie, ICQ_VERSION, (BYTE)pCookieData->bMessageType, 0,
- wPriority, 0, 0, (BYTE)((pCookieData->nAckType == ACKTYPE_SERVER) ? 1 : 0));
-
- packLEWord(&packet, WORD(nBodyLen + 1)); // Length of message
- packBuffer(&packet, (LPBYTE)szMessage, nBodyLen + 1); // Message
- packMsgColorInfo(&packet);
-
- if (szCap) {
- packLEDWord(&packet, 0x00000026); // length of GUID
- packBuffer(&packet, (LPBYTE)szCap, 0x26); // UTF-8 GUID
- }
-
- // Pack request server ack TLV
- if (pCookieData->nAckType == ACKTYPE_SERVER)
- packDWord(&packet, 0x00030000); // TLV(3)
-
- sendServPacket(&packet);
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_SendChannel2Contacts(DWORD dwUin, char *szUid, MCONTACT hContact, const char *pData, size_t wDataLen, const char *pNames, size_t wNamesLen, cookie_message_data *pCookieData)
-{
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, pCookieData);
-
- size_t wPacketLength = wDataLen + wNamesLen + 0x12;
-
- // Pack the standard header
- icq_packet packet;
- packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, szUid, 2, wPacketLength + ((pCookieData->nAckType == ACKTYPE_SERVER) ? 0x22 : 0x1E));
-
- packServTLV5HeaderBasic(&packet, wPacketLength, pCookieData->dwMsgID1, pCookieData->dwMsgID2, 0, MCAP_CONTACTS);
-
- packTLVWord(&packet, 0x0A, 1); // TLV: 0x0A Acktype: 1 for normal, 2 for ack
- packDWord(&packet, 0x000F0000); // TLV: 0x0F empty
- packTLV(&packet, 0x2711, wDataLen, (LPBYTE)pData); // TLV: 0x2711 Content (Contact UIDs)
- packTLV(&packet, 0x2712, wNamesLen, (LPBYTE)pNames);// TLV: 0x2712 Extended Content (Contact NickNames)
-
- // Pack request ack TLV
- if (pCookieData->nAckType == ACKTYPE_SERVER) {
- packDWord(&packet, 0x00030000); // TLV(3)
- }
-
- sendServPacket(&packet);
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_SendChannel4Message(DWORD dwUin, MCONTACT hContact, BYTE bMsgType, size_t wMsgLen, const char *szMsg, cookie_message_data *pCookieData)
-{
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
- size_t wPacketLength = (pCookieData->nAckType == ACKTYPE_SERVER) ? 28 : 24;
-
- // Pack the standard header
- icq_packet packet;
- packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, nullptr, 4, wPacketLength + wMsgLen);
-
- // Pack first TLV
- packWord(&packet, 0x05); // TLV(5)
- packWord(&packet, WORD(wMsgLen + 16)); // TLV len
- packLEDWord(&packet, m_dwLocalUIN); // My UIN
- packByte(&packet, bMsgType); // Message type
- packByte(&packet, 0); // Message flags
- packLEWord(&packet, WORD(wMsgLen)); // Message length
- packBuffer(&packet, (LPBYTE)szMsg, wMsgLen); // Message text
- packMsgColorInfo(&packet);
-
- // Pack request ack TLV
- if (pCookieData->nAckType == ACKTYPE_SERVER)
- packDWord(&packet, 0x00030000); // TLV(3)
-
- // Pack store on server TLV
- packDWord(&packet, 0x00060000); // TLV(6)
-
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-
-void CIcqProto::sendOwnerInfoRequest(void)
-{
- icq_packet packet;
-
- if (m_bLegacyFix) {
- cookie_fam15_data *pCookieData = (cookie_fam15_data*)SAFE_MALLOC(sizeof(cookie_fam15_data));
- pCookieData->bRequestType = REQUESTTYPE_OWNER;
- DWORD dwCookie = AllocateCookie(CKT_FAMILYSPECIAL, 0, NULL, (void*)pCookieData);
-
- packServIcqExtensionHeader(&packet, this, 6, 0x07D0, (WORD)dwCookie);
- packLEWord(&packet, META_REQUEST_SELF_INFO);
- packLEDWord(&packet, m_dwLocalUIN);
- }
- else {
- cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data));
- pCookieData->bRequestType = DIRECTORYREQUEST_INFOOWNER;
-
- DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_QUERY, 0, NULL, (void*)pCookieData);
- WORD wDataLen = getUINLen(m_dwLocalUIN) + 4;
-
- packServIcqDirectoryHeader(&packet, this, wDataLen + 8, META_DIRECTORY_QUERY, DIRECTORY_QUERY_INFO, (WORD)dwCookie);
- packWord(&packet, 0x03); // with interests (ICQ6 uses 2 at login)
- packDWord(&packet, 0x01);
- packWord(&packet, wDataLen);
-
- packTLVUID(&packet, 0x32, m_dwLocalUIN, nullptr);
- }
-
- sendServPacket(&packet);
-}
-
-DWORD CIcqProto::sendUserInfoMultiRequest(BYTE *pRequestData, size_t dataLen, int nItems)
-{
- cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data));
- if (!pCookieData)
- return 0; // Failure
-
- pCookieData->bRequestType = DIRECTORYREQUEST_INFOMULTI;
- DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_QUERY, 0, NULL, (void*)pCookieData);
-
- icq_packet packet;
- packServIcqDirectoryHeader(&packet, this, dataLen + 2, META_DIRECTORY_QUERY, DIRECTORY_QUERY_MULTI_INFO, (WORD)dwCookie);
- packWord(&packet, nItems);
- packBuffer(&packet, pRequestData, dataLen);
-
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_sendGetInfoServ(MCONTACT hContact, DWORD dwUin, int bManual)
-{
- if (IsServerOverRate(ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST, bManual ? RML_IDLE_10 : RML_IDLE_50))
- return 0;
-
- DBVARIANT infoToken = { DBVT_DELETED };
- BYTE *pToken = nullptr;
- WORD cbToken = 0;
-
- if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &infoToken)) { // retrieve user details using privacy token
- cbToken = infoToken.cpbVal;
- pToken = (BYTE*)_alloca(cbToken);
- memcpy(pToken, infoToken.pbVal, cbToken);
-
- db_free(&infoToken);
- }
-
- cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data));
-
- icq_packet packet;
- if (m_bLegacyFix) {
- pCookieData->bRequestType = REQUESTTYPE_USERDETAILED;
-
- DWORD dwCookie = AllocateCookie(CKT_FAMILYSPECIAL, 0, hContact, (void*)pCookieData);
-
- packServIcqExtensionHeader(&packet, this, 6, CLI_META_INFO_REQ, (WORD)dwCookie);
- packLEWord(&packet, META_REQUEST_FULL_INFO);
- packLEDWord(&packet, dwUin);
-
- sendServPacket(&packet);
- return dwCookie;
- }
-
- pCookieData->bRequestType = DIRECTORYREQUEST_INFOUSER;
-
- DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_QUERY, 0, hContact, (void*)pCookieData);
- WORD wDataLen = cbToken + getUINLen(dwUin) + (cbToken ? 8 : 4);
-
- packServIcqDirectoryHeader(&packet, this, wDataLen + 8, META_DIRECTORY_QUERY, DIRECTORY_QUERY_INFO, (WORD)dwCookie);
- packWord(&packet, 0x03);
- packDWord(&packet, 1);
- packWord(&packet, wDataLen);
- if (pToken)
- packTLV(&packet, 0x3C, cbToken, pToken);
- packTLVUID(&packet, 0x32, dwUin, nullptr);
-
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-
-DWORD CIcqProto::icq_sendGetAimProfileServ(MCONTACT hContact, char* szUid)
-{
- if (IsServerOverRate(ICQ_LOCATION_FAMILY, ICQ_LOCATION_REQ_USER_INFO, RML_IDLE_10))
- return 0;
-
- cookie_fam15_data *pCookieData = (cookie_fam15_data*)SAFE_MALLOC(sizeof(cookie_fam15_data));
- pCookieData->bRequestType = REQUESTTYPE_PROFILE;
-
- DWORD dwCookie = AllocateCookie(CKT_FAMILYSPECIAL, ICQ_LOCATION_REQ_USER_INFO, hContact, (void*)pCookieData);
- BYTE bUIDlen = (BYTE)mir_strlen(szUid);
-
- icq_packet packet;
- serverPacketInit(&packet, 13 + bUIDlen);
- packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_REQ_USER_INFO, 0, dwCookie);
- packWord(&packet, 0x01); // request profile info
- packByte(&packet, bUIDlen);
- packBuffer(&packet, (LPBYTE)szUid, bUIDlen);
-
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-
-DWORD CIcqProto::icq_sendGetAwayMsgServ(MCONTACT hContact, DWORD dwUin, int type, WORD wVersion)
-{
- if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_IDLE_30))
- return 0;
-
- cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_AUTOAWAY, (BYTE)type);
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
-
- icq_packet packet;
- packServChannel2Header(&packet, this, dwUin, 3, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwCookie, wVersion, (BYTE)type, 3, 1, 0, 0, 0);
- packEmptyMsg(&packet); // Message
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-
-DWORD CIcqProto::icq_sendGetAwayMsgServExt(MCONTACT hContact, DWORD dwUin, char *szUID, int type, WORD wVersion)
-{
- if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_IDLE_30))
- return 0;
-
- cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_AUTOAWAY, (BYTE)type);
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
-
- icq_packet packet;
- packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, szUID, 2, 122 + getPluginTypeIdLen(type));
-
- // TLV(5) header
- packServTLV5HeaderMsg(&packet, 82 + getPluginTypeIdLen(type), pCookieData->dwMsgID1, pCookieData->dwMsgID2, 1);
-
- // TLV(0x2711) header
- packServTLV2711Header(&packet, (WORD)dwCookie, wVersion, MTYPE_PLUGIN, 0, 0, 0x100, 27 + getPluginTypeIdLen(type));
-
- packLEWord(&packet, 0); // Empty msg
-
- packPluginTypeId(&packet, type);
-
- packLEDWord(&packet, 0x15);
- packLEDWord(&packet, 0);
- packLEDWord(&packet, 0x0D);
- packBuffer(&packet, (LPBYTE)"text/x-aolrtf", 0x0D);
-
- // Send the monster
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-
-DWORD CIcqProto::icq_sendGetAimAwayMsgServ(MCONTACT hContact, char *szUID, int type)
-{
- BYTE bUIDlen = (BYTE)mir_strlen(szUID);
-
- cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_AUTOAWAY, (byte)type);
- DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData);
-
- icq_packet packet;
- serverPacketInit(&packet, 13 + bUIDlen);
- packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_REQ_USER_INFO, 0, dwCookie);
- packWord(&packet, 0x03);
- packUID(&packet, 0, szUID);
-
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-
-void CIcqProto::icq_sendSetAimAwayMsgServ(const char *szMsg)
-{
- icq_packet packet;
- size_t wMsgLen = mir_strlen(szMsg);
-
- DWORD dwCookie = GenerateCookie(ICQ_LOCATION_SET_USER_INFO);
-
- if (wMsgLen) {
- if (wMsgLen > 0x1000) wMsgLen = 0x1000; // limit length
-
- if (IsUSASCII(szMsg, wMsgLen)) {
- const char* fmt = "text/x-aolrtf; charset=\"us-ascii\"";
- size_t fmtlen = mir_strlen(fmt);
-
- serverPacketInit(&packet, 23 + wMsgLen + fmtlen);
- packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_SET_USER_INFO, 0, dwCookie);
- packTLV(&packet, 0x0f, 1, (LPBYTE)"\x02");
- packTLV(&packet, 0x03, fmtlen, (LPBYTE)fmt);
- packTLV(&packet, 0x04, wMsgLen, (LPBYTE)szMsg);
- }
- else {
- const char* fmt = "text/x-aolrtf; charset=\"unicode-2-0\"";
- size_t fmtlen = mir_strlen(fmt);
-
- WCHAR *szMsgW = make_unicode_string(szMsg);
- wMsgLen = mir_wstrlen(szMsgW) * sizeof(WCHAR);
-
- WCHAR *szMsgW2 = (WCHAR*)alloca(wMsgLen), *szMsgW3 = szMsgW;
- unpackWideString((BYTE**)&szMsgW3, szMsgW2, wMsgLen);
- SAFE_FREE(&szMsgW);
-
- serverPacketInit(&packet, 23 + wMsgLen + fmtlen);
- packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_SET_USER_INFO, 0, dwCookie);
- packTLV(&packet, 0x0f, 1, (LPBYTE)"\x02");
- packTLV(&packet, 0x03, fmtlen, (LPBYTE)fmt);
- packTLV(&packet, 0x04, wMsgLen, (LPBYTE)szMsgW2);
- }
- }
- else {
- serverPacketInit(&packet, 19);
- packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_SET_USER_INFO, 0, dwCookie);
- packTLV(&packet, 0x0f, 1, (LPBYTE)"\x02");
- packTLV(&packet, 0x04, 0, nullptr);
- }
-
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendFileSendServv7(filetransfer* ft, const char *szFiles)
-{
- char *szFilesAnsi = nullptr, *szDescrAnsi = nullptr;
-
- if (!utf8_decode(szFiles, &szFilesAnsi))
- szFilesAnsi = _strdup(szFiles); // Legacy fix
-
- if (!utf8_decode(ft->szDescription, &szDescrAnsi))
- szDescrAnsi = _strdup(ft->szDescription); // Legacy fix
-
- size_t wFilesLen = mir_strlen(szFilesAnsi);
- size_t wDescrLen = mir_strlen(szDescrAnsi);
-
- icq_packet packet;
- packServChannel2Header(&packet, this, ft->dwUin, 18 + wDescrLen + wFilesLen, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ICQ_VERSION, MTYPE_FILEREQ, 0, 1, 0, 1, 1);
-
- packLEWord(&packet, WORD(wDescrLen + 1));
- packBuffer(&packet, (LPBYTE)szDescrAnsi, wDescrLen + 1);
- packLEDWord(&packet, 0); // unknown
- packLEWord(&packet, WORD(wFilesLen + 1));
- packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1);
- packLEDWord(&packet, ft->dwTotalSize);
- packLEDWord(&packet, 0); // unknown
-
- SAFE_FREE(&szFilesAnsi);
- SAFE_FREE(&szDescrAnsi);
-
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendFileSendServv8(filetransfer* ft, const char *szFiles, int nAckType)
-{
- icq_packet packet;
- char *szFilesAnsi = nullptr, *szDescrAnsi = nullptr;
-
- if (!utf8_decode(szFiles, &szFilesAnsi))
- szFilesAnsi = _strdup(szFiles); // Legacy fix
-
- if (!utf8_decode(ft->szDescription, &szDescrAnsi))
- szDescrAnsi = _strdup(ft->szDescription); // Legacy fix
-
- size_t wFilesLen = mir_strlen(szFilesAnsi);
- size_t wDescrLen = mir_strlen(szDescrAnsi);
-
- // 202 + UIN len + file description (no null) + file name (null included)
- // Packet size = Flap length + 4
- size_t wFlapLen = 178 + wDescrLen + wFilesLen + (nAckType == ACKTYPE_SERVER ? 4 : 0);
- packServMsgSendHeader(&packet, ft->dwCookie, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwUin, nullptr, 2, wFlapLen);
-
- // TLV(5) header
- packServTLV5HeaderMsg(&packet, 138 + wDescrLen + wFilesLen, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, 1);
-
- // Port & IP information
- packServDCInfo(&packet, this, FALSE);
-
- // TLV(0x2711) header
- packServTLV2711Header(&packet, (WORD)ft->dwCookie, ICQ_VERSION, MTYPE_PLUGIN, 0, MirandaStatusToIcq(m_iStatus), 0x100, 69 + wDescrLen + wFilesLen);
-
- packEmptyMsg(&packet); // Message (unused)
-
- packPluginTypeId(&packet, MTYPE_FILEREQ);
-
- packLEDWord(&packet, WORD(18 + wDescrLen + wFilesLen + 1)); // Remaining length
- packLEDWord(&packet, DWORD(wDescrLen)); // Description
- packBuffer(&packet, (LPBYTE)szDescrAnsi, wDescrLen);
- packWord(&packet, 0x8c82); // Unknown (port?), seen 0x80F6
- packWord(&packet, 0x0222); // Unknown, seen 0x2e01
- packLEWord(&packet, WORD(wFilesLen + 1));
- packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1);
- packLEDWord(&packet, ft->dwTotalSize);
- packLEDWord(&packet, 0x0008c82); // Unknown, (seen 0xf680 ~33000)
-
- SAFE_FREE(&szFilesAnsi);
- SAFE_FREE(&szDescrAnsi);
-
- // Pack request server ack TLV
- if (nAckType == ACKTYPE_SERVER)
- packDWord(&packet, 0x00030000); // TLV(3)
-
- // Send the monster
- sendServPacket(&packet);
-}
-
-
-/* also sends rejections */
-void CIcqProto::icq_sendFileAcceptServv8(DWORD dwUin, DWORD TS1, DWORD TS2, DWORD dwCookie, const char *szFiles, const char *szDescr, DWORD dwTotalSize, WORD wPort, BOOL accepted, int nAckType)
-{
- icq_packet packet;
- char *szFilesAnsi = nullptr, *szDescrAnsi = nullptr;
-
- /* if !accepted, szDescr == szReason, szFiles = "" */
-
- if (!accepted) szFiles = "";
-
- if (!utf8_decode(szFiles, &szFilesAnsi))
- szFilesAnsi = _strdup(szFiles); // Legacy fix
-
- if (!utf8_decode(szDescr, &szDescrAnsi))
- szDescrAnsi = _strdup(szDescr); // Legacy fix
-
- size_t wDescrLen = mir_strlen(szDescrAnsi);
- size_t wFilesLen = mir_strlen(szFilesAnsi);
-
- // 202 + UIN len + file description (no null) + file name (null included)
- // Packet size = Flap length + 4
- size_t wFlapLen = 178 + wDescrLen + wFilesLen + (nAckType == ACKTYPE_SERVER ? 4 : 0);
- packServMsgSendHeader(&packet, dwCookie, TS1, TS2, dwUin, nullptr, 2, wFlapLen);
-
- // TLV(5) header
- packServTLV5HeaderMsg(&packet, 138 + wDescrLen + wFilesLen, TS1, TS2, 2);
-
- // Port & IP information
- packServDCInfo(&packet, this, !accepted);
-
- // TLV(0x2711) header
- packServTLV2711Header(&packet, (WORD)dwCookie, ICQ_VERSION, MTYPE_PLUGIN, 0, (WORD)(accepted ? 0 : 1), 0, 69 + wDescrLen + wFilesLen);
- //
- packEmptyMsg(&packet); // Message (unused)
-
- packPluginTypeId(&packet, MTYPE_FILEREQ);
-
- packLEDWord(&packet, DWORD(18 + wDescrLen + wFilesLen + 1)); // Remaining length
- packLEDWord(&packet, DWORD(wDescrLen)); // Description
- packBuffer(&packet, (LPBYTE)szDescrAnsi, wDescrLen);
- packWord(&packet, wPort); // Port
- packWord(&packet, 0x00); // Unknown
- packLEWord(&packet, WORD(wFilesLen + 1));
- packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1);
- packLEDWord(&packet, dwTotalSize);
- packLEDWord(&packet, (DWORD)wPort); // Unknown
-
- SAFE_FREE(&szFilesAnsi);
- SAFE_FREE(&szDescrAnsi);
-
- // Pack request server ack TLV
- if (nAckType == ACKTYPE_SERVER) {
- packDWord(&packet, 0x00030000); // TLV(3)
- }
-
- // Send the monster
- sendServPacket(&packet);
-}
-
-
-void CIcqProto::icq_sendFileAcceptServv7(DWORD dwUin, DWORD TS1, DWORD TS2, DWORD dwCookie, const char* szFiles, const char* szDescr, DWORD dwTotalSize, WORD wPort, BOOL accepted, int nAckType)
-{
- icq_packet packet;
- char *szFilesAnsi = nullptr, *szDescrAnsi = nullptr;
-
- /* if !accepted, szDescr == szReason, szFiles = "" */
-
- if (!accepted) szFiles = "";
-
- if (!utf8_decode(szFiles, &szFilesAnsi))
- szFilesAnsi = _strdup(szFiles); // Legacy fix
-
- if (!utf8_decode(szDescr, &szDescrAnsi))
- szDescrAnsi = _strdup(szDescr); // Legacy fix
-
- size_t wDescrLen = mir_strlen(szDescrAnsi);
- size_t wFilesLen = mir_strlen(szFilesAnsi);
-
- // 150 + UIN len + file description (with null) + file name (2 nulls)
- // Packet size = Flap length + 4
- size_t wFlapLen = 127 + wDescrLen + 1 + wFilesLen + (nAckType == ACKTYPE_SERVER ? 4 : 0);
- packServMsgSendHeader(&packet, dwCookie, TS1, TS2, dwUin, nullptr, 2, wFlapLen);
-
- // TLV(5) header
- packServTLV5HeaderMsg(&packet, 88 + wDescrLen + wFilesLen, TS1, TS2, 2);
-
- // Port & IP information
- packServDCInfo(&packet, this, !accepted);
-
- // TLV(0x2711) header
- packServTLV2711Header(&packet, (WORD)dwCookie, ICQ_VERSION, MTYPE_FILEREQ, 0, (WORD)(accepted ? 0 : 1), 0, 19 + wDescrLen + wFilesLen);
- //
- packLEWord(&packet, WORD(wDescrLen + 1)); // Description
- packBuffer(&packet, (LPBYTE)szDescrAnsi, wDescrLen + 1);
- packWord(&packet, wPort); // Port
- packWord(&packet, 0x00); // Unknown
- packLEWord(&packet, WORD(wFilesLen + 2));
- packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1);
- packByte(&packet, 0);
- packLEDWord(&packet, dwTotalSize);
- packLEDWord(&packet, (DWORD)wPort); // Unknown
-
- SAFE_FREE(&szFilesAnsi);
- SAFE_FREE(&szDescrAnsi);
-
- // Pack request server ack TLV
- if (nAckType == ACKTYPE_SERVER)
- packDWord(&packet, 0x00030000); // TLV(3)
-
- // Send the monster
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendFileAcceptServ(DWORD dwUin, filetransfer *ft, int nAckType)
-{
- char *szDesc = ft->szDescription;
-
- if (ft->bEmptyDesc) szDesc = ""; // keep empty if it originally was (Trillian workaround)
-
- if (ft->nVersion >= 8) {
- icq_sendFileAcceptServv8(dwUin, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ft->szFilename, szDesc, ft->dwTotalSize, wListenPort, TRUE, nAckType);
- debugLogA("Sent file accept v%u through server, port %u", 8, wListenPort);
- }
- else {
- icq_sendFileAcceptServv7(dwUin, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ft->szFilename, szDesc, ft->dwTotalSize, wListenPort, TRUE, nAckType);
- debugLogA("Sent file accept v%u through server, port %u", 7, wListenPort);
- }
-}
-
-void CIcqProto::icq_sendFileDenyServ(DWORD dwUin, filetransfer *ft, const char *szReason, int nAckType)
-{
- if (ft->nVersion >= 8) {
- icq_sendFileAcceptServv8(dwUin, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ft->szFilename, szReason, ft->dwTotalSize, wListenPort, FALSE, nAckType);
- debugLogA("Sent file deny v%u through server", 8);
- }
- else {
- icq_sendFileAcceptServv7(dwUin, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ft->szFilename, szReason, ft->dwTotalSize, wListenPort, FALSE, nAckType);
- debugLogA("Sent file deny v%u through server", 7);
- }
-}
-
-void CIcqProto::icq_sendAwayMsgReplyServ(DWORD dwUin, DWORD dwMsgID1, DWORD dwMsgID2, WORD wCookie, WORD wVersion, BYTE msgType, char** szMsg)
-{
- MCONTACT hContact = HContactFromUIN(dwUin, nullptr);
-
- if (validateStatusMessageRequest(hContact, msgType)) {
- NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dwUin);
-
- mir_cslock l(m_modeMsgsMutex);
-
- if (szMsg && *szMsg) {
- char *pszMsg = nullptr;
- WORD wReplyVersion = ICQ_VERSION;
-
- if (wVersion >= 9) {
- pszMsg = *szMsg;
- wReplyVersion = 9;
- }
- else { // only v9 protocol supports UTF-8 mode messagees
- size_t wMsgLen = mir_strlen(*szMsg) + 1;
- char *szAnsiMsg = (char*)_alloca(wMsgLen);
-
- utf8_decode_static(*szMsg, szAnsiMsg, wMsgLen);
- pszMsg = szAnsiMsg;
- }
-
- // limit msg len to max snac size - we get disconnected if exceeded
- size_t wMsgLen = mir_strlen(pszMsg);
- if (wMsgLen > MAX_MESSAGESNACSIZE)
- wMsgLen = MAX_MESSAGESNACSIZE;
-
- icq_packet packet;
- packServAdvancedMsgReply(&packet, dwUin, nullptr, dwMsgID1, dwMsgID2, wCookie, wReplyVersion, msgType, 3, wMsgLen + 3);
- packLEWord(&packet, WORD(wMsgLen + 1));
- packBuffer(&packet, (LPBYTE)pszMsg, wMsgLen);
- packByte(&packet, 0);
-
- sendServPacket(&packet);
- }
- }
-}
-
-
-void CIcqProto::icq_sendAwayMsgReplyServExt(DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wCookie, WORD wVersion, BYTE msgType, char **szMsg)
-{
- MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr);
-
- if (validateStatusMessageRequest(hContact, msgType)) {
- NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dwUin);
-
- mir_cslock l(m_modeMsgsMutex);
-
- if (szMsg && *szMsg) {
- char *pszMsg = nullptr;
- WORD wReplyVersion = ICQ_VERSION;
-
- if (wVersion >= 9)
- pszMsg = *szMsg;
- else { // only v9 protocol supports UTF-8 mode messagees
- wReplyVersion = 8;
-
- size_t wMsgLen = mir_strlen(*szMsg) + 1;
- char *szAnsiMsg = (char*)_alloca(wMsgLen);
-
- utf8_decode_static(*szMsg, szAnsiMsg, wMsgLen);
- pszMsg = szAnsiMsg;
- }
- // convert to HTML
- char *mng = MangleXml(pszMsg, mir_strlen(pszMsg));
- pszMsg = (char*)SAFE_MALLOC(mir_strlen(mng) + 28);
- mir_strcpy(pszMsg, "<HTML><BODY>"); /// TODO: add support for RTL & user customizable font
- mir_strcat(pszMsg, mng);
- SAFE_FREE(&mng);
- mir_strcat(pszMsg, "</BODY></HTML>");
-
- // limit msg len to max snac size - we get disconnected if exceeded /// FIXME: correct HTML cutting
- size_t wMsgLen = mir_strlen(pszMsg);
- if (wMsgLen > MAX_MESSAGESNACSIZE)
- wMsgLen = MAX_MESSAGESNACSIZE;
-
- icq_packet packet;
- packServAdvancedMsgReply(&packet, dwUin, szUID, dwMsgID1, dwMsgID2, wCookie, wReplyVersion, MTYPE_PLUGIN, 0, wMsgLen + 27 + getPluginTypeIdLen(msgType));
- packLEWord(&packet, 0); // Message size
- packPluginTypeId(&packet, msgType);
-
- packLEDWord(&packet, DWORD(wMsgLen + 21));
- packLEDWord(&packet, DWORD(wMsgLen));
- packBuffer(&packet, (LPBYTE)pszMsg, wMsgLen);
-
- packLEDWord(&packet, 0x0D);
- packBuffer(&packet, (LPBYTE)"text/x-aolrtf", 0x0D);
-
- sendServPacket(&packet);
- SAFE_FREE(&pszMsg);
- }
- }
-}
-
-
-void CIcqProto::icq_sendAdvancedMsgAck(DWORD dwUin, DWORD dwTimestamp, DWORD dwTimestamp2, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags)
-{
- icq_packet packet;
- packServAdvancedMsgReply(&packet, dwUin, nullptr, dwTimestamp, dwTimestamp2, wCookie, ICQ_VERSION, bMsgType, bMsgFlags, 11);
- packEmptyMsg(&packet); // Status message
- packMsgColorInfo(&packet);
-
- sendServPacket(&packet);
-}
-
-
-void CIcqProto::icq_sendContactsAck(DWORD dwUin, char *szUid, DWORD dwMsgID1, DWORD dwMsgID2)
-{
- icq_packet packet;
- packServMsgSendHeader(&packet, 0, dwMsgID1, dwMsgID2, dwUin, szUid, 2, 0x1E);
- packServTLV5HeaderBasic(&packet, 0, dwMsgID1, dwMsgID2, 2, MCAP_CONTACTS);
-
- sendServPacket(&packet);
-}
-
-
-// Searches
-
-DWORD CIcqProto::SearchByUin(DWORD dwUin)
-{
- WORD wInfoLen;
- icq_packet pBuffer; // I reuse the ICQ packet type as a generic buffer
- // I should be ashamed! ;)
- if (m_bLegacyFix) {
- // Calculate data size
- wInfoLen = 8;
-
- // Initialize our handy data buffer
- pBuffer.wPlace = 0;
- pBuffer.pData = (BYTE *)_alloca(wInfoLen);
- pBuffer.wLen = wInfoLen;
-
- // Initialize our handy data buffer
- packLEWord(&pBuffer, TLV_UIN);
- packLEWord(&pBuffer, 0x0004);
- packLEDWord(&pBuffer, dwUin);
-
- // Send it off for further packing
- return sendTLVSearchPacket(SEARCHTYPE_UID, (char*)pBuffer.pData, META_SEARCH_UIN, wInfoLen, FALSE);
- }
-
- // Calculate data size
- wInfoLen = 4 + getUINLen(dwUin);
-
- // Initialize our handy data buffer
- pBuffer.wPlace = 0;
- pBuffer.pData = (BYTE *)_alloca(wInfoLen);
- pBuffer.wLen = wInfoLen;
-
- // Initialize our handy data buffer
- packTLVUID(&pBuffer, 0x32, dwUin, nullptr);
-
- // Send it off for further packing
- return sendDirectorySearchPacket(pBuffer.pData, wInfoLen, 0, FALSE);
-}
-
-
-DWORD CIcqProto::SearchByNames(const char *pszNick, const char *pszFirstName, const char *pszLastName, WORD wPage)
-{ // use directory search like ICQ6 does
- size_t wInfoLen = 0;
- icq_packet pBuffer; // I reuse the ICQ packet type as a generic buffer
- // I should be ashamed! ;)
- if (m_bLegacyFix) {
- // Legacy protocol uses ANSI-string searches
-
- char* pszNickAnsi = nullptr;
- if (!utf8_decode(pszNick, &pszNickAnsi))
- pszNickAnsi = _strdup(pszNick);
-
- char* pszFirstNameAnsi = nullptr;
- if (!utf8_decode(pszFirstName, &pszFirstNameAnsi))
- pszFirstNameAnsi = _strdup(pszFirstName);
-
- char* pszLastNameAnsi = nullptr;
- if (!utf8_decode(pszLastName, &pszLastNameAnsi))
- pszLastNameAnsi = _strdup(pszLastName);
-
- size_t wNickLen = mir_strlen(pszNickAnsi);
- size_t wFirstLen = mir_strlen(pszFirstNameAnsi);
- size_t wLastLen = mir_strlen(pszLastNameAnsi);
-
- _ASSERTE(wFirstLen || wLastLen || wNickLen);
-
- // Calculate data size
- if (wFirstLen > 0)
- wInfoLen = wFirstLen + 7;
- if (wLastLen > 0)
- wInfoLen += wLastLen + 7;
- if (wNickLen > 0)
- wInfoLen += wNickLen + 7;
-
- // Initialize our handy data buffer
- pBuffer.wPlace = 0;
- pBuffer.pData = (BYTE *)_alloca(wInfoLen);
- pBuffer.wLen = WORD(wInfoLen);
-
- size_t pBufferPos = 0;
-
- // Pack the search details
- if (wFirstLen > 0)
- packLETLVLNTS(&pBuffer.pData, &pBufferPos, pszFirstNameAnsi, TLV_FIRSTNAME);
-
- if (wLastLen > 0)
- packLETLVLNTS(&pBuffer.pData, &pBufferPos, pszLastNameAnsi, TLV_LASTNAME);
-
- if (wNickLen > 0)
- packLETLVLNTS(&pBuffer.pData, &pBufferPos, pszNickAnsi, TLV_NICKNAME);
-
- SAFE_FREE(&pszFirstNameAnsi);
- SAFE_FREE(&pszLastNameAnsi);
- SAFE_FREE(&pszNickAnsi);
-
- // Send it off for further packing
- return sendTLVSearchPacket(SEARCHTYPE_NAMES, (char*)pBuffer.pData, META_SEARCH_GENERIC, wInfoLen, FALSE);
- }
-
- size_t wNickLen = mir_strlen(pszNick);
- size_t wFirstLen = mir_strlen(pszFirstName);
- size_t wLastLen = mir_strlen(pszLastName);
-
- _ASSERTE(wFirstLen || wLastLen || wNickLen);
-
- // Calculate data size
- if (wFirstLen)
- wInfoLen = wFirstLen + 4;
- if (wLastLen)
- wInfoLen += wLastLen + 4;
- if (wNickLen)
- wInfoLen += wNickLen + 4;
-
- // Initialize our handy data buffer
- pBuffer.wPlace = 0;
- pBuffer.pData = (BYTE *)_alloca(wInfoLen);
- pBuffer.wLen = WORD(wInfoLen);
-
- // Pack the search details
- if (wNickLen)
- packTLV(&pBuffer, 0x78, wNickLen, (PBYTE)pszNick);
-
- if (wLastLen)
- packTLV(&pBuffer, 0x6E, wLastLen, (PBYTE)pszLastName);
-
- if (wFirstLen)
- packTLV(&pBuffer, 0x64, wFirstLen, (PBYTE)pszFirstName);
-
- // Send it off for further packing
- if (wInfoLen)
- return sendDirectorySearchPacket(pBuffer.pData, wInfoLen, wPage, FALSE);
- else
- return 0; // Failure
-}
-
-DWORD CIcqProto::SearchByMail(const char* pszEmail)
-{
- size_t wEmailLen = mir_strlen(pszEmail);
- _ASSERTE(wEmailLen);
- if (wEmailLen <= 0)
- return 0;
-
- // Calculate data size
- size_t wInfoLen = wEmailLen + 7;
-
- // Initialize our handy data buffer
- BYTE *pBuffer = (BYTE *)_alloca(wInfoLen);
- size_t pBufferPos = 0;
-
- // Pack the search details
- packLETLVLNTS(&pBuffer, &pBufferPos, pszEmail, TLV_EMAIL);
-
- // Send it off for further packing
- return sendTLVSearchPacket(SEARCHTYPE_EMAIL, (char*)pBuffer, META_SEARCH_EMAIL, wInfoLen, FALSE);
-}
-
-DWORD CIcqProto::sendDirectorySearchPacket(const BYTE *pSearchData, size_t wDataLen, WORD wPage, BOOL bOnlineUsersOnly)
-{
- _ASSERTE(pSearchData);
- _ASSERTE(wDataLen >= 4);
-
- cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data));
- if (pCookieData == nullptr)
- return 0;
-
- pCookieData->bRequestType = DIRECTORYREQUEST_SEARCH;
- DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_QUERY, 0, NULL, (void*)pCookieData);
-
- // Pack headers
- icq_packet packet;
- packServIcqDirectoryHeader(&packet, this, wDataLen + (bOnlineUsersOnly ? 14 : 8), META_DIRECTORY_QUERY, DIRECTORY_QUERY_INFO, (WORD)dwCookie);
- packWord(&packet, 0x02);
-
- // Pack requested page number
- packWord(&packet, wPage);
-
- // Pack search data
- packWord(&packet, 0x0001);
- packWord(&packet, WORD(wDataLen + (bOnlineUsersOnly ? 6 : 0)));
- packBuffer(&packet, pSearchData, wDataLen);
-
- if (bOnlineUsersOnly) // Pack "Online users only" flag
- packTLVWord(&packet, 0x136, 1);
-
- // Go!
- sendServPacket(&packet);
- return dwCookie;
-}
-
-DWORD CIcqProto::sendTLVSearchPacket(BYTE bType, char* pSearchDataBuf, WORD wSearchType, size_t wInfoLen, BOOL bOnlineUsersOnly)
-{
- _ASSERTE(pSearchDataBuf);
- _ASSERTE(wInfoLen >= 4);
-
- cookie_search *pCookie = (cookie_search*)SAFE_MALLOC(sizeof(cookie_search));
- if (!pCookie)
- return 0;
-
- pCookie->bSearchType = bType;
- DWORD dwCookie = AllocateCookie(CKT_SEARCH, 0, 0, pCookie);
-
- // Pack headers
- icq_packet packet;
- packServIcqExtensionHeader(&packet, this, wInfoLen + (wSearchType == META_SEARCH_GENERIC ? 7 : 2), CLI_META_INFO_REQ, (WORD)dwCookie);
-
- // Pack search type
- packLEWord(&packet, wSearchType);
-
- // Pack search data
- packBuffer(&packet, (LPBYTE)pSearchDataBuf, wInfoLen);
-
- if (wSearchType == META_SEARCH_GENERIC && bOnlineUsersOnly) { // Pack "Online users only" flag - only for generic search
- BYTE bData = 1;
- packTLV(&packet, TLV_ONLINEONLY, 1, &bData);
- }
-
- // Go!
- sendServPacket(&packet);
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_sendAdvancedSearchServ(BYTE* fieldsBuffer, size_t bufferLen)
-{
- cookie_search *pCookie = (cookie_search*)SAFE_MALLOC(sizeof(cookie_search));
- if (pCookie == nullptr)
- return 0;
-
- pCookie->bSearchType = SEARCHTYPE_DETAILS;
- DWORD dwCookie = AllocateCookie(CKT_SEARCH, 0, 0, pCookie);
-
- icq_packet packet;
- packServIcqExtensionHeader(&packet, this, bufferLen, CLI_META_INFO_REQ, (WORD)dwCookie);
- packBuffer(&packet, (LPBYTE)fieldsBuffer, bufferLen);
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_searchAimByEmail(const char* pszEmail, DWORD dwSearchId)
-{
- cookie_search *pCookie;
- if (!FindCookie(dwSearchId, nullptr, (void**)&pCookie)) {
- dwSearchId = 0;
- pCookie = (cookie_search*)SAFE_MALLOC(sizeof(cookie_search));
- pCookie->bSearchType = SEARCHTYPE_EMAIL;
- }
-
- if (!pCookie)
- return 0;
-
- pCookie->dwMainId = dwSearchId;
- pCookie->szObject = null_strdup(pszEmail);
- DWORD dwCookie = AllocateCookie(CKT_SEARCH, ICQ_LOOKUP_REQUEST, 0, pCookie);
-
- size_t wEmailLen = mir_strlen(pszEmail);
- icq_packet packet;
- serverPacketInit(&packet, 10 + wEmailLen);
- packFNACHeader(&packet, ICQ_LOOKUP_FAMILY, ICQ_LOOKUP_REQUEST, 0, dwCookie);
- packBuffer(&packet, (LPBYTE)pszEmail, wEmailLen);
-
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_changeUserPasswordServ(const char *szPassword)
-{
- size_t wPasswordLen = mir_strlen(szPassword);
- DWORD dwCookie = GenerateCookie(0);
-
- icq_packet packet;
- packServIcqExtensionHeader(&packet, this, wPasswordLen + 4, CLI_META_INFO_REQ, (WORD)dwCookie, ICQ_META_SRV_UPDATE);
- packLEWord(&packet, META_SET_PASSWORD_REQ);
- packLEWord(&packet, WORD(wPasswordLen));
- packBuffer(&packet, (BYTE*)szPassword, wPasswordLen);
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_changeUserDirectoryInfoServ(const BYTE *pData, size_t wDataLen, BYTE bRequestType)
-{
- cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data));
- pCookieData->bRequestType = bRequestType;
- DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_UPDATE, 0, NULL, pCookieData);
-
- icq_packet packet;
- packServIcqDirectoryHeader(&packet, this, wDataLen + 4, META_DIRECTORY_UPDATE, DIRECTORY_SET_INFO, (WORD)dwCookie, ICQ_META_SRV_UPDATE);
- packWord(&packet, 0x0003);
- packWord(&packet, WORD(wDataLen));
- packBuffer(&packet, pData, wDataLen);
- sendServPacket(&packet);
-
- return dwCookie;
-}
-
-DWORD CIcqProto::icq_sendSMSServ(const char *szPhoneNumber, const char *szMsg)
-{
- DWORD dwCookie;
- WORD wBufferLen;
- char *szBuffer = nullptr;
- char szTime[30];
- time_t now = time(0);
- strftime(szTime, sizeof(szTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
- /* Sun, 00 Jan 0000 00:00:00 GMT */
-
- char *szMyNick = null_strdup(_T2A(Clist_GetContactDisplayName(0)));
- size_t nBufferSize = 1 + mir_strlen(szMyNick) + mir_strlen(szPhoneNumber) + mir_strlen(szMsg) + sizeof("<icq_sms_message><destination></destination><text></text><codepage>1252</codepage><encoding>utf8</encoding><senders_UIN>0000000000</senders_UIN><senders_name></senders_name><delivery_receipt>Yes</delivery_receipt><time>Sun, 00 Jan 0000 00:00:00 GMT</time></icq_sms_message>");
-
- if (szBuffer = (char *)_alloca(nBufferSize)) {
- wBufferLen = mir_snprintf(szBuffer, nBufferSize,
- "<icq_sms_message>"
- "<destination>"
- "%s" /* phone number */
- "</destination>"
- "<text>"
- "%s" /* body */
- "</text>"
- "<codepage>"
- "1252"
- "</codepage>"
- "<encoding>"
- "utf8"
- "</encoding>"
- "<senders_UIN>"
- "%u" /* my UIN */
- "</senders_UIN>"
- "<senders_name>"
- "%s" /* my nick */
- "</senders_name>"
- "<delivery_receipt>"
- "Yes"
- "</delivery_receipt>"
- "<time>"
- "%s" /* time */
- "</time>"
- "</icq_sms_message>",
- szPhoneNumber, szMsg, m_dwLocalUIN, szMyNick, szTime);
-
- dwCookie = GenerateCookie(0);
-
- icq_packet packet;
- packServIcqExtensionHeader(&packet, this, wBufferLen + 27, CLI_META_INFO_REQ, (WORD)dwCookie);
- packWord(&packet, 0x8214); /* send sms */
- packWord(&packet, 1);
- packWord(&packet, 0x16);
- packDWord(&packet, 0);
- packDWord(&packet, 0);
- packDWord(&packet, 0);
- packDWord(&packet, 0);
- packWord(&packet, 0);
- packWord(&packet, WORD(wBufferLen + 1));
- packBuffer(&packet, (LPBYTE)szBuffer, wBufferLen + 1);
-
- sendServPacket(&packet);
- }
- else dwCookie = 0;
-
- SAFE_FREE((void**)&szMyNick);
- return dwCookie;
-}
-
-void CIcqProto::icq_sendGenericContact(DWORD dwUin, const char *szUid, WORD wFamily, WORD wSubType)
-{
- int nUinLen = getUIDLen(dwUin, szUid);
-
- icq_packet packet;
- serverPacketInit(&packet, nUinLen + 11);
- packFNACHeader(&packet, wFamily, wSubType);
- packUID(&packet, dwUin, szUid);
-
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendNewContact(DWORD dwUin, const char *szUid)
-{
- /* Try to add to temporary buddy list */
- icq_sendGenericContact(dwUin, szUid, ICQ_BUDDY_FAMILY, ICQ_USER_ADDTOTEMPLIST);
-}
-
-void CIcqProto::icq_sendRemoveContact(DWORD dwUin, const char *szUid)
-{
- /* Remove from temporary buddy list */
- icq_sendGenericContact(dwUin, szUid, ICQ_BUDDY_FAMILY, ICQ_USER_REMOVEFROMTEMPLIST);
-}
-
-// list==0: visible list
-// list==1: invisible list
-void CIcqProto::icq_sendChangeVisInvis(MCONTACT hContact, DWORD dwUin, char* szUID, int list, int add)
-{
- // TODO: This needs grouping & rate management
- // Tell server to change our server-side contact visbility list
- if (m_bSsiEnabled) {
- WORD wContactId;
- char* szSetting;
- WORD wType;
-
- if (list == 0) {
- wType = SSI_ITEM_PERMIT;
- szSetting = DBSETTING_SERVLIST_PERMIT;
- }
- else {
- wType = SSI_ITEM_DENY;
- szSetting = DBSETTING_SERVLIST_DENY;
- }
-
- if (add) {
- // check if we should make the changes, this is 2nd level check
- if (getWord(hContact, szSetting, 0) != 0)
- return;
-
- // Add
- wContactId = GenerateServerID(SSIT_ITEM, 0);
-
- icq_addServerPrivacyItem(hContact, dwUin, szUID, wContactId, wType);
-
- setWord(hContact, szSetting, wContactId);
- }
- else {
- // Remove
- wContactId = getWord(hContact, szSetting, 0);
-
- if (wContactId) {
- icq_removeServerPrivacyItem(hContact, dwUin, szUID, wContactId, wType);
-
- delSetting(hContact, szSetting);
- }
- }
- }
-
- // Notify server that we have changed
- // our client side visibility list
- if (list && m_iStatus == ID_STATUS_INVISIBLE)
- return;
-
- if (!list && m_iStatus != ID_STATUS_INVISIBLE)
- return;
-
- WORD wSnac = 0;
- if (list && add)
- wSnac = ICQ_CLI_ADDINVISIBLE;
- else if (list && !add)
- wSnac = ICQ_CLI_REMOVEINVISIBLE;
- else if (!list && add)
- wSnac = ICQ_CLI_ADDVISIBLE;
- else if (!list && !add)
- wSnac = ICQ_CLI_REMOVEVISIBLE;
-
- int nUinLen = getUIDLen(dwUin, szUID);
-
- icq_packet packet;
- serverPacketInit(&packet, nUinLen + 11);
- packFNACHeader(&packet, ICQ_BOS_FAMILY, wSnac);
- packUID(&packet, dwUin, szUID);
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendEntireVisInvisList(int list)
-{
- if (list)
- sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDINVISIBLE, BUL_INVISIBLE);
- else
- sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDVISIBLE, BUL_VISIBLE);
-}
-
-void CIcqProto::icq_sendRevokeAuthServ(DWORD dwUin, char *szUid)
-{
- icq_sendGenericContact(dwUin, szUid, ICQ_LISTS_FAMILY, ICQ_LISTS_REVOKEAUTH);
-}
-
-void CIcqProto::icq_sendGrantAuthServ(DWORD dwUin, const char *szUid, const char *szMsg)
-{
- BYTE nUinlen = getUIDLen(dwUin, szUid);
-
- // Prepare custom utf-8 message
- char *szUtfMsg = ansi_to_utf8(szMsg);
- size_t nMsglen = mir_strlen(szUtfMsg);
-
- icq_packet packet;
- serverPacketInit(&packet, 15 + nUinlen + nMsglen);
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_GRANTAUTH);
- packUID(&packet, dwUin, szUid);
- packWord(&packet, WORD(nMsglen));
- packBuffer(&packet, (LPBYTE)szUtfMsg, nMsglen);
- packWord(&packet, 0);
-
- SAFE_FREE((void**)&szUtfMsg);
-
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendAuthReqServ(DWORD dwUin, char *szUid, const char *szMsg)
-{
- BYTE nUinlen = getUIDLen(dwUin, szUid);
- size_t nMsglen = mir_strlen(szMsg);
-
- icq_packet packet;
- serverPacketInit(&packet, 15 + nUinlen + nMsglen);
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_REQUESTAUTH);
- packUID(&packet, dwUin, szUid);
- packWord(&packet, WORD(nMsglen));
- packBuffer(&packet, (LPBYTE)szMsg, nMsglen);
- packWord(&packet, 0);
-
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendAuthResponseServ(DWORD dwUin, char* szUid, int auth, const wchar_t *szReason)
-{
- BYTE nUinLen = getUIDLen(dwUin, szUid);
-
- // Prepare custom utf-8 reason
- char *szUtfReason = make_utf8_string(szReason);
- size_t nReasonLen = mir_strlen(szUtfReason);
-
- icq_packet packet;
- serverPacketInit(&packet, 16 + nUinLen + nReasonLen);
- packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_AUTHRESPONSE);
- packUID(&packet, dwUin, szUid);
- packByte(&packet, (BYTE)auth);
- packWord(&packet, WORD(nReasonLen));
- packBuffer(&packet, (LPBYTE)szUtfReason, nReasonLen);
- packWord(&packet, 0);
-
- SAFE_FREE(&szUtfReason);
-
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendYouWereAddedServ(DWORD dwUin, DWORD dwMyUin)
-{
- DWORD dwID1 = time(0);
- DWORD dwID2 = RandRange(0, 0x00FF);
-
- icq_packet packet;
- packServMsgSendHeader(&packet, 0, dwID1, dwID2, dwUin, nullptr, 0x0004, 17);
- packWord(&packet, 0x0005); // TLV(5)
- packWord(&packet, 0x0009);
- packLEDWord(&packet, dwMyUin);
- packByte(&packet, MTYPE_ADDED);
- packByte(&packet, 0); // msg-flags
- packEmptyMsg(&packet); // NTS
- packDWord(&packet, 0x00060000); // TLV(6)
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendXtrazRequestServ(DWORD dwUin, DWORD dwCookie, char* szBody, size_t nBodyLen, cookie_message_data *pCookieData)
-{
- size_t wCoreLen = 11 + getPluginTypeIdLen(pCookieData->bMessageType) + nBodyLen;
-
- icq_packet packet;
- packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, nullptr, 2, 99 + wCoreLen);
-
- // TLV(5) header
- packServTLV5HeaderMsg(&packet, 55 + wCoreLen, pCookieData->dwMsgID1, pCookieData->dwMsgID2, 1);
-
- // TLV(0x2711) header
- packServTLV2711Header(&packet, (WORD)dwCookie, ICQ_VERSION, MTYPE_PLUGIN, 0, 0, 0x100, wCoreLen);
- //
- packEmptyMsg(&packet);
-
- packPluginTypeId(&packet, pCookieData->bMessageType);
-
- packLEDWord(&packet, DWORD(nBodyLen + 4));
- packLEDWord(&packet, DWORD(nBodyLen));
- packBuffer(&packet, (LPBYTE)szBody, nBodyLen);
-
- // Pack request server ack TLV
- packDWord(&packet, 0x00030000); // TLV(3)
-
- // Send the monster
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendXtrazResponseServ(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szBody, size_t nBodyLen, int nType)
-{
- icq_packet packet;
- packServAdvancedMsgReply(&packet, dwUin, nullptr, dwMID, dwMID2, wCookie, ICQ_VERSION, MTYPE_PLUGIN, 0, getPluginTypeIdLen(nType) + 11 + nBodyLen);
-
- packEmptyMsg(&packet);
-
- packPluginTypeId(&packet, nType);
-
- packLEDWord(&packet, DWORD(nBodyLen + 4));
- packLEDWord(&packet, DWORD(nBodyLen));
- packBuffer(&packet, (LPBYTE)szBody, nBodyLen);
-
- // Send the monster
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendReverseReq(directconnect *dc, DWORD dwCookie, cookie_message_data *pCookie)
-{
- icq_packet packet;
- packServMsgSendHeader(&packet, dwCookie, pCookie->dwMsgID1, pCookie->dwMsgID2, dc->dwRemoteUin, nullptr, 2, 0x47);
-
- packServTLV5HeaderBasic(&packet, 0x29, pCookie->dwMsgID1, pCookie->dwMsgID2, 0, MCAP_REVERSE_DC_REQ);
-
- packTLVWord(&packet, 0x0A, 1); // TLV: 0x0A Acktype: 1 for normal, 2 for ack
- packDWord(&packet, 0x000F0000); // TLV: 0x0F empty
- packDWord(&packet, 0x2711001B); // TLV: 0x2711 Content
- // TLV(0x2711) data
- packLEDWord(&packet, m_dwLocalUIN); // Our UIN
- packDWord(&packet, dc->dwLocalExternalIP);// IP to connect to
- packLEDWord(&packet, wListenPort); // Port to connect to
- packByte(&packet, DC_NORMAL); // generic DC type
- packDWord(&packet, dc->dwRemotePort); // unknown
- packDWord(&packet, wListenPort); // port again ?
- packLEWord(&packet, ICQ_VERSION); // DC Version
- packLEDWord(&packet, dwCookie); // Req Cookie
-
- // Send the monster
- sendServPacket(&packet);
-}
-
-void CIcqProto::icq_sendReverseFailed(directconnect* dc, DWORD dwMsgID1, DWORD dwMsgID2, DWORD dwCookie)
-{
- int nUinLen = getUINLen(dc->dwRemoteUin);
-
- icq_packet packet;
- serverPacketInit(&packet, nUinLen + 74);
- packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE, 0, ICQ_MSG_RESPONSE << 0x10 | (dwCookie & 0x7FFF));
- packLEDWord(&packet, dwMsgID1); // Msg ID part 1
- packLEDWord(&packet, dwMsgID2); // Msg ID part 2
- packWord(&packet, 0x02);
- packUIN(&packet, dc->dwRemoteUin);
- packWord(&packet, 0x03);
- packLEDWord(&packet, dc->dwRemoteUin);
- packLEDWord(&packet, dc->dwRemotePort);
- packLEDWord(&packet, wListenPort);
- packLEWord(&packet, ICQ_VERSION);
- packLEDWord(&packet, dwCookie);
-
- sendServPacket(&packet);
-}
-
-// OSCAR file-transfer packets starts here
-//
-void CIcqProto::oft_sendFileRequest(DWORD dwUin, char *szUid, oscar_filetransfer *ft, const char *pszFiles, DWORD dwLocalInternalIP)
-{
- size_t size = mir_strlen(ft->szDescription) + mir_strlen(pszFiles) + 160;
- char *szCoolStr = (char *)_alloca(size);
- mir_snprintf(szCoolStr, size, "<ICQ_COOL_FT><FS>%s</FS><S>%I64u</S><SID>1</SID><DESC>%s</DESC></ICQ_COOL_FT>", pszFiles, ft->qwTotalSize, ft->szDescription);
- szCoolStr = MangleXml(szCoolStr, mir_strlen(szCoolStr));
-
- size_t wDataLen = 93 + mir_strlen(szCoolStr) + mir_strlen(pszFiles);
- if (ft->bUseProxy)
- wDataLen += 4;
-
- icq_packet packet;
- packServMsgSendHeader(&packet, ft->dwCookie, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, dwUin, szUid, 2, wDataLen + 0x1E);
- packServTLV5HeaderBasic(&packet, wDataLen, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, 0, MCAP_FILE_TRANSFER);
-
- packTLVWord(&packet, 0x0A, ++ft->wReqNum); // Request sequence
- packDWord(&packet, 0x000F0000); // Unknown
- packTLV(&packet, 0x0D, 5, (LPBYTE)"utf-8"); // Charset
- packTLV(&packet, 0x0C, mir_strlen(szCoolStr), (LPBYTE)szCoolStr); // User message (CoolData XML)
- SAFE_FREE(&szCoolStr);
- if (ft->bUseProxy) {
- packTLVDWord(&packet, 0x02, ft->dwProxyIP); // Proxy IP
- packTLVDWord(&packet, 0x16, ft->dwProxyIP ^ 0x0FFFFFFFF); // Proxy IP check
- }
- else {
- packTLVDWord(&packet, 0x02, dwLocalInternalIP);
- packTLVDWord(&packet, 0x16, dwLocalInternalIP ^ 0x0FFFFFFFF);
- }
- packTLVDWord(&packet, 0x03, dwLocalInternalIP); // Client IP
- if (ft->bUseProxy) {
- packTLVWord(&packet, 0x05, ft->wRemotePort);
- packTLVWord(&packet, 0x17, WORD(ft->wRemotePort ^ 0x0FFFF));
- packDWord(&packet, 0x00100000); // Proxy flag
- }
- else {
- oscar_listener *pListener = (oscar_listener*)ft->listener;
- packTLVWord(&packet, 0x05, pListener->wPort);
- packTLVWord(&packet, 0x15, WORD((pListener->wPort) ^ 0x0FFFF));
- }
-
- // TLV(0x2711)
- packWord(&packet, 0x2711);
- packWord(&packet, WORD(9 + mir_strlen(pszFiles)));
- packWord(&packet, WORD(ft->wFilesCount == 1 ? 1 : 2));
- packWord(&packet, ft->wFilesCount);
- packDWord(&packet, (DWORD)ft->qwTotalSize);
- packBuffer(&packet, (LPBYTE)pszFiles, mir_strlen(pszFiles) + 1);
-
- packTLV(&packet, 0x2712, 5, (LPBYTE)"utf-8");
-
- // TLV(0x2713)
- packWord(&packet, 0x2713);
- packWord(&packet, 8);
- packQWord(&packet, ft->qwTotalSize);
-
- sendServPacket(&packet); // Send the monster
-}
-
-
-void CIcqProto::oft_sendFileReply(DWORD dwUin, char *szUid, oscar_filetransfer *ft, WORD wResult)
-{
- icq_packet packet;
- packServMsgSendHeader(&packet, 0, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, dwUin, szUid, 2, 0x1E);
- packServTLV5HeaderBasic(&packet, 0, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, wResult, MCAP_FILE_TRANSFER);
- sendServPacket(&packet);
-}
-
-
-void CIcqProto::oft_sendFileAccept(DWORD dwUin, char *szUid, oscar_filetransfer *ft)
-{
- oft_sendFileReply(dwUin, szUid, ft, 0x02);
-}
-
-void CIcqProto::oft_sendFileResponse(DWORD dwUin, char *szUid, oscar_filetransfer *ft, WORD wResponse)
-{
- icq_packet packet;
- packServAdvancedReply(&packet, dwUin, szUid, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, 0, 4);
- packWord(&packet, 0x02); // Length of following data
- packWord(&packet, wResponse); // Response code
- sendServPacket(&packet);
-}
-
-void CIcqProto::oft_sendFileDeny(DWORD dwUin, char *szUid, oscar_filetransfer *ft)
-{
- if (dwUin) // ICQ clients uses special deny file transfer
- oft_sendFileResponse(dwUin, szUid, ft, 0x01);
- else
- oft_sendFileReply(dwUin, szUid, ft, 0x01);
-}
-
-void CIcqProto::oft_sendFileCancel(DWORD dwUin, char *szUid, oscar_filetransfer *ft)
-{
- oft_sendFileReply(dwUin, szUid, ft, 0x01);
-}
-
-void CIcqProto::oft_sendFileRedirect(DWORD dwUin, char *szUid, oscar_filetransfer *ft, DWORD dwIP, WORD wPort, int bProxy)
-{
- icq_packet packet;
- packServMsgSendHeader(&packet, 0, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, dwUin, szUid, 2, bProxy ? 0x4a : 0x4e);
- packServTLV5HeaderBasic(&packet, bProxy ? 0x2C : 0x30, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, 0, MCAP_FILE_TRANSFER);
- // Connection point data
- packTLVWord(&packet, 0x0A, ++ft->wReqNum); // Ack Type
- packTLVWord(&packet, 0x14, 0x0A); // Unknown ?
- packTLVDWord(&packet, 0x02, dwIP); // Internal IP / Proxy IP
- packTLVDWord(&packet, 0x16, dwIP ^ 0x0FFFFFFFF); // IP Check ?
- if (!bProxy)
- packTLVDWord(&packet, 0x03, dwIP);
- packTLVWord(&packet, 0x05, wPort); // Listening Port
- packTLVWord(&packet, 0x17, WORD(wPort ^ 0x0FFFF)); // Port Check ?
- if (bProxy)
- packDWord(&packet, 0x00100000); // Proxy Flag
-
- sendServPacket(&packet);
-}
diff --git a/protocols/IcqOscarJ/src/stdpackets.h b/protocols/IcqOscarJ/src/stdpackets.h
deleted file mode 100644
index cb5b8a683c..0000000000
--- a/protocols/IcqOscarJ/src/stdpackets.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Low-level functions that really sends data to server
-// -----------------------------------------------------------------------------
-
-#ifndef __STDPACKETS_H
-#define __STDPACKETS_H
-
-struct icq_contactsend_s
-{
- DWORD uin;
- char *uid;
- char *szNick;
-};
-
-
-void packMsgColorInfo(icq_packet *packet);
-
-#endif /* __STDPACKETS_H */
diff --git a/protocols/IcqOscarJ/src/tlv.cpp b/protocols/IcqOscarJ/src/tlv.cpp
deleted file mode 100644
index c2edc68dde..0000000000
--- a/protocols/IcqOscarJ/src/tlv.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Helper functions for Oscar TLV chains
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-/* set maxTlvs<=0 to get all TLVs in length, or a positive integer to get at most the first n */
-oscar_tlv_chain* readIntoTLVChain(BYTE **buf, size_t wLen, int maxTlvs)
-{
- oscar_tlv_chain *now, *last = nullptr, *chain = nullptr;
- WORD now_tlv_len;
-
- if (!buf || !wLen)
- return nullptr;
-
- intptr_t len = wLen;
- while (len > 0) { /* don't use unsigned variable for this check */
- now = (oscar_tlv_chain *)SAFE_MALLOC(sizeof(oscar_tlv_chain));
-
- if (!now) {
- disposeChain(&chain);
- return nullptr;
- }
-
- unpackWord(buf, &(now->tlv.wType));
- unpackWord(buf, &now_tlv_len);
- now->tlv.wLen = now_tlv_len;
- len -= 4;
-
- if (now_tlv_len < 1)
- now->tlv.pData = nullptr;
- else if (now_tlv_len <= len) {
- now->tlv.pData = (BYTE *)SAFE_MALLOC(now_tlv_len);
- if (now->tlv.pData)
- memcpy(now->tlv.pData, *buf, now_tlv_len);
- }
- else { // the packet is shorter than it should be
- SAFE_FREE((void**)&now);
- return chain; // give at least the rest of chain
- }
-
- if (chain) // keep the original order
- last->next = now;
- else
- chain = now;
-
- last = now;
-
- len -= now_tlv_len;
- *buf += now_tlv_len;
-
- if (--maxTlvs == 0)
- break;
- }
-
- return chain;
-}
-
-// Returns a pointer to the TLV with type wType and number wIndex in the chain
-// If wIndex = 1, the first matching TLV will be returned, if wIndex = 2,
-// the second matching one will be returned.
-// wIndex must be > 0
-oscar_tlv* oscar_tlv_chain::getTLV(WORD wType, WORD wIndex)
-{
- int i = 0;
- oscar_tlv_chain *list = this;
-
- while (list) {
- if (list->tlv.wType == wType)
- i++;
- if (i >= wIndex)
- return &list->tlv;
- list = list->next;
- }
-
- return nullptr;
-}
-
-WORD oscar_tlv_chain::getChainLength()
-{
- int len = 0;
- oscar_tlv_chain *list = this;
-
- while (list) {
- len += list->tlv.wLen + 4;
- list = list->next;
- }
- return len;
-}
-
-oscar_tlv* oscar_tlv_chain::putTLV(WORD wType, size_t wLen, BYTE *pData, BOOL bReplace)
-{
- oscar_tlv *pTLV = getTLV(wType, 1);
-
- if (pTLV && bReplace)
- SAFE_FREE((void**)&pTLV->pData);
- else {
- oscar_tlv_chain *last = this;
-
- while (last && last->next)
- last = last->next;
-
- if (last) {
- last->next = (oscar_tlv_chain*)SAFE_MALLOC(sizeof(oscar_tlv_chain));
- pTLV = &last->next->tlv;
- pTLV->wType = wType;
- }
- }
- if (pTLV) {
- pTLV->wLen = WORD(wLen);
- pTLV->pData = (PBYTE)SAFE_MALLOC(wLen);
- memcpy(pTLV->pData, pData, wLen);
- }
- return pTLV;
-}
-
-oscar_tlv_chain* oscar_tlv_chain::removeTLV(oscar_tlv *pTLV)
-{
- oscar_tlv_chain *list = this, *prev = nullptr, *chain = this;
- while (list) {
- if (&list->tlv == pTLV) {
- if (prev) // relink
- prev->next = list->next;
- else if (list->next) { // move second item's pTLV to the first item
- list->tlv = list->next->tlv;
- list = list->next;
- }
- else // result is an empty chain (NULL)
- chain = nullptr;
- // release chain item memory
- SAFE_FREE((void**)&list->tlv.pData);
- SAFE_FREE((void**)&list);
- }
- prev = list;
- list = list->next;
- }
-
- return chain;
-}
-
-WORD oscar_tlv_chain::getLength(WORD wType, WORD wIndex)
-{
- oscar_tlv *pTLV = getTLV(wType, wIndex);
- if (pTLV)
- return pTLV->wLen;
-
- return 0;
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-/* Values are returned in MSB format */
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-DWORD oscar_tlv_chain::getDWord(WORD wType, WORD wIndex)
-{
- DWORD dw = 0;
-
- oscar_tlv *pTLV = getTLV(wType, wIndex);
- if (pTLV && pTLV->wLen >= 4) {
- dw |= (*((pTLV->pData) + 0) << 24);
- dw |= (*((pTLV->pData) + 1) << 16);
- dw |= (*((pTLV->pData) + 2) << 8);
- dw |= (*((pTLV->pData) + 3));
- }
-
- return dw;
-}
-
-WORD oscar_tlv_chain::getWord(WORD wType, WORD wIndex)
-{
- WORD w = 0;
-
- oscar_tlv *pTLV = getTLV(wType, wIndex);
- if (pTLV && pTLV->wLen >= 2) {
- w |= (*((pTLV->pData) + 0) << 8);
- w |= (*((pTLV->pData) + 1));
- }
-
- return w;
-}
-
-BYTE oscar_tlv_chain::getByte(WORD wType, WORD wIndex)
-{
- BYTE b = 0;
-
- oscar_tlv *pTLV = getTLV(wType, wIndex);
- if (pTLV && pTLV->wLen)
- b = *(pTLV->pData);
-
- return b;
-}
-
-int oscar_tlv_chain::getNumber(WORD wType, WORD wIndex)
-{
- oscar_tlv *pTLV = getTLV(wType, wIndex);
- if (pTLV) {
- if (pTLV->wLen == 1)
- return getByte(wType, wIndex);
- if (pTLV->wLen == 2)
- return getWord(wType, wIndex);
- if (pTLV->wLen == 4)
- return getDWord(wType, wIndex);
- }
- return 0;
-}
-
-double oscar_tlv_chain::getDouble(WORD wType, WORD wIndex)
-{
- oscar_tlv *pTLV = getTLV(wType, wIndex);
- if (pTLV && pTLV->wLen == 8) {
- BYTE *buf = pTLV->pData;
- double d = 0;
-
- unpackQWord(&buf, (DWORD64*)&d);
-
- return d;
- }
- return 0;
-}
-
-char* oscar_tlv_chain::getString(WORD wType, WORD wIndex)
-{
- oscar_tlv *pTLV = getTLV(wType, wIndex);
- if (pTLV) {
- char *str = (char*)SAFE_MALLOC(pTLV->wLen + 1); /* For \0 */
- if (!str)
- return nullptr;
-
- memcpy(str, pTLV->pData, pTLV->wLen);
- str[pTLV->wLen] = '\0';
- return str;
- }
-
- return nullptr;
-}
-
-void disposeChain(oscar_tlv_chain **chain)
-{
- if (!chain || !*chain)
- return;
-
- oscar_tlv_chain *now = *chain;
- while (now) {
- oscar_tlv_chain *next = now->next;
-
- SAFE_FREE((void**)&now->tlv.pData);
- SAFE_FREE((void**)&now);
- now = next;
- }
-
- *chain = nullptr;
-}
-
-oscar_tlv_record_list* readIntoTLVRecordList(BYTE **buf, size_t wLen, int nCount)
-{
- oscar_tlv_record_list *list = nullptr, *last = nullptr;
-
- while (wLen >= 2) {
- WORD wRecordSize;
-
- unpackWord(buf, &wRecordSize);
- wLen -= 2;
- if (wRecordSize && wRecordSize <= wLen) {
- oscar_tlv_record_list *pRecord = (oscar_tlv_record_list*)SAFE_MALLOC(sizeof(oscar_tlv_record_list));
- BYTE *pData = *buf;
-
- *buf += wRecordSize;
- wLen -= wRecordSize;
-
- pRecord->item = readIntoTLVChain(&pData, wRecordSize, 0);
- if (pRecord->item) { // keep the order
- if (list)
- last->next = pRecord;
- else
- list = pRecord;
-
- last = pRecord;
- }
- else SAFE_FREE((void**)&pRecord);
- }
-
- if (--nCount == 0)
- break;
- }
- return list;
-}
-
-void disposeRecordList(oscar_tlv_record_list** list)
-{
- if (!list || !*list)
- return;
-
- oscar_tlv_record_list *now = *list;
-
- while (now) {
- oscar_tlv_record_list *next = now->next;
-
- disposeChain(&now->item);
- SAFE_FREE((void**)&now);
- now = next;
- }
-
- *list = nullptr;
-}
-
-oscar_tlv_chain* oscar_tlv_record_list::getRecordByTLV(WORD wType, int nValue)
-{
- oscar_tlv_record_list *list = this;
- while (list) {
- if (list->item && list->item->getTLV(wType, 1) && list->item->getNumber(wType, 1) == nValue)
- return list->item;
- list = list->next;
- }
-
- return nullptr;
-}
diff --git a/protocols/IcqOscarJ/src/tlv.h b/protocols/IcqOscarJ/src/tlv.h
deleted file mode 100644
index fb1d594cae..0000000000
--- a/protocols/IcqOscarJ/src/tlv.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2008 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-
-#ifndef __TLV_H
-#define __TLV_H
-
-/*---------* Structures *--------------*/
-
-struct oscar_tlv
-{
- WORD wType;
- WORD wLen;
- BYTE *pData;
-};
-
-struct oscar_tlv_chain
-{
- oscar_tlv tlv;
- oscar_tlv_chain *next;
-
- WORD getChainLength();
-
- oscar_tlv* getTLV(WORD wType, WORD wIndex);
- oscar_tlv* putTLV(WORD wType, size_t wLen, BYTE *pData, BOOL bReplace);
- oscar_tlv_chain* removeTLV(oscar_tlv *tlv);
- WORD getLength(WORD wType, WORD wIndex);
-
- DWORD getDWord(WORD wType, WORD wIndex);
- WORD getWord(WORD wType, WORD wIndex);
- BYTE getByte(WORD wType, WORD wIndex);
- int getNumber(WORD wType, WORD wIndex);
- double getDouble(WORD wType, WORD wIndex);
- char* getString(WORD wType, WORD wIndex);
-};
-
-
-struct oscar_tlv_record_list
-{
- oscar_tlv_chain *item;
- oscar_tlv_record_list *next;
-
- oscar_tlv_chain* getRecordByTLV(WORD wType, int nValue);
-};
-
-/*---------* Functions *---------------*/
-
-oscar_tlv_chain* readIntoTLVChain(BYTE **buf, size_t wLen, int maxTlvs);
-void disposeChain(oscar_tlv_chain** chain);
-
-oscar_tlv_record_list* readIntoTLVRecordList(BYTE **buf, size_t wLen, int nCount);
-void disposeRecordList(oscar_tlv_record_list** list);
-
-
-#endif /* __TLV_H */
diff --git a/protocols/IcqOscarJ/src/upload.cpp b/protocols/IcqOscarJ/src/upload.cpp
deleted file mode 100644
index f6741d1e7c..0000000000
--- a/protocols/IcqOscarJ/src/upload.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2001-2004 Richard Hughes, Martin Öberg
-// Copyright © 2004-2009 Joe Kucera, Bio
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// ChangeInfo Plugin stuff
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-int CIcqProto::StringToListItemId(const char *szSetting, int def)
-{
- int i;
-
- for (i = 0; i < settingCount; i++)
- if (!mir_strcmp(szSetting, setting[i].szDbSetting))
- break;
-
- if (i == settingCount)
- return def;
-
- FieldNamesItem *list = (FieldNamesItem*)setting[i].pList;
-
- char *szValue = getSettingStringUtf(NULL, szSetting, nullptr);
- if (!szValue)
- return def;
-
- for (i = 0; list[i].text; i++)
- if (!mir_strcmp(list[i].text, szValue))
- break;
-
- SAFE_FREE(&szValue);
- if (!list[i].text) return def;
-
- return list[i].code;
-}
-
-
-int ChangeInfoData::UploadSettings(void)
-{
- if (!ppro->icqOnline()) {
- MessageBox(hwndDlg, TranslateT("You are not currently connected to the ICQ network. You must be online in order to update your information on the server."), TranslateT("Change ICQ Details"), MB_OK);
- return 0;
- }
-
- hUpload[0] = (HANDLE)ppro->ChangeInfoEx(CIXT_FULL, 0);
-
- //password
- char* tmp = ppro->GetUserPassword(TRUE);
- if (tmp) {
- if (mir_strlen(Password) > 0 && mir_strcmp(Password, tmp)) {
- // update password in user info dialog (still open)
- mir_strcpy(Password, tmp);
- // update password in protocol
- mir_strcpy(ppro->m_szPassword, tmp);
-
- hUpload[1] = (HANDLE)ppro->icq_changeUserPasswordServ(tmp);
-
- // password is stored in DB, update
- char szPwd[PASSWORDMAXLEN + 1];
- if (ppro->GetUserStoredPassword(szPwd))
- ppro->setString("Password", tmp);
- }
- }
-
- return 1;
-}
diff --git a/protocols/IcqOscarJ/src/userinfotab.cpp b/protocols/IcqOscarJ/src/userinfotab.cpp
deleted file mode 100644
index 305cc33a9a..0000000000
--- a/protocols/IcqOscarJ/src/userinfotab.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Code for User details ICQ specific pages
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-#define SVS_NORMAL 0
-#define SVS_ZEROISUNSPEC 2
-#define SVS_IP 3
-#define SVS_SIGNED 6
-#define SVS_ICQVERSION 8
-#define SVS_TIMESTAMP 9
-#define SVS_STATUSID 10
-
-extern const char *nameXStatus[];
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static void SetValue(CIcqProto* ppro, HWND hwndDlg, int idCtrl, MCONTACT hContact, char* szModule, char* szSetting, int special)
-{
- DBVARIANT dbv = { 0 };
- char str[MAX_PATH];
- char* pstr = nullptr;
- int unspecified = 0;
- int bUtf = 0, bDbv = 0, bAlloc = 0;
-
- dbv.type = DBVT_DELETED;
-
- if ((hContact == NULL) && ((INT_PTR)szModule < 0x100)) {
- dbv.type = (INT_PTR)szModule;
-
- switch ((INT_PTR)szModule) {
- case DBVT_BYTE:
- dbv.cVal = (INT_PTR)szSetting;
- break;
- case DBVT_WORD:
- dbv.wVal = (INT_PTR)szSetting;
- break;
- case DBVT_DWORD:
- dbv.dVal = (UINT_PTR)szSetting;
- break;
- case DBVT_ASCIIZ:
- dbv.pszVal = pstr = szSetting;
- break;
- default:
- unspecified = 1;
- dbv.type = DBVT_DELETED;
- }
- }
- else {
- if (szModule == nullptr)
- unspecified = 1;
- else {
- unspecified = db_get(hContact, szModule, szSetting, &dbv);
- bDbv = 1;
- }
- }
-
- if (!unspecified) {
- switch (dbv.type) {
- case DBVT_BYTE:
- unspecified = (special == SVS_ZEROISUNSPEC && dbv.bVal == 0);
- pstr = _itoa(special == SVS_SIGNED ? dbv.cVal : dbv.bVal, str, 10);
- break;
-
- case DBVT_WORD:
- if (special == SVS_ICQVERSION) {
- if (dbv.wVal != 0) {
- char szExtra[80];
-
- mir_snprintf(str, "%d", dbv.wVal);
- pstr = str;
-
- if (hContact && ppro->IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 1)) {
- ICQTranslateUtfStatic(LPGEN(" (DC Established)"), szExtra, _countof(szExtra));
- mir_strcat(str, (char*)szExtra);
- bUtf = 1;
- }
- }
- else
- unspecified = 1;
- }
- else if (special == SVS_STATUSID) {
- char *pszStatus = MirandaStatusToStringUtf(dbv.wVal);
- BYTE bXStatus = ppro->getContactXStatus(hContact);
-
- if (bXStatus) {
- char *pXName = ppro->getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, nullptr);
- if (pXName == nullptr) // give default name
- pXName = ICQTranslateUtf(nameXStatus[bXStatus - 1]);
-
- mir_snprintf(str, "%s (%s)", pszStatus, pXName);
- SAFE_FREE((void**)&pXName);
- }
- else strncpy_s(str, pszStatus, _TRUNCATE);
-
- bUtf = 1;
- SAFE_FREE(&pszStatus);
- pstr = str;
- unspecified = 0;
- }
- else {
- unspecified = (special == SVS_ZEROISUNSPEC && dbv.wVal == 0);
- pstr = _itoa(special == SVS_SIGNED ? dbv.sVal : dbv.wVal, str, 10);
- }
- break;
-
- case DBVT_DWORD:
- unspecified = (special == SVS_ZEROISUNSPEC && dbv.dVal == 0);
- if (special == SVS_IP) {
- struct in_addr ia;
- ia.S_un.S_addr = htonl(dbv.dVal);
- pstr = inet_ntoa(ia);
- if (dbv.dVal == 0)
- unspecified = 1;
- }
- else if (special == SVS_TIMESTAMP) {
- if (dbv.dVal == 0)
- unspecified = 1;
- else
- pstr = time2text(dbv.dVal);
- }
- else
- pstr = _itoa(special == SVS_SIGNED ? dbv.lVal : dbv.dVal, str, 10);
- break;
-
- case DBVT_ASCIIZ:
- case DBVT_WCHAR:
- unspecified = (special == SVS_ZEROISUNSPEC && dbv.pszVal[0] == '\0');
- if (!unspecified && pstr != szSetting) {
- pstr = ppro->getSettingStringUtf(hContact, szModule, szSetting, nullptr);
- bUtf = 1;
- bAlloc = 1;
- }
- if (idCtrl == IDC_UIN)
- SetDlgItemText(hwndDlg, IDC_UINSTATIC, TranslateT("ScreenName:"));
- break;
-
- default:
- pstr = str;
- mir_strcpy(str, "???");
- break;
- }
- }
-
- EnableDlgItem(hwndDlg, idCtrl, !unspecified);
- if (unspecified)
- SetDlgItemText(hwndDlg, idCtrl, TranslateT("<not specified>"));
- else if (bUtf)
- SetDlgItemTextUtf(hwndDlg, idCtrl, pstr);
- else
- SetDlgItemTextA(hwndDlg, idCtrl, pstr);
-
- if (bDbv)
- db_free(&dbv);
-
- if (bAlloc)
- SAFE_FREE(&pstr);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static INT_PTR CALLBACK IcqDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->idFrom) {
- case 0:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_PARAMCHANGED:
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, ((PSHNOTIFY*)lParam)->lParam);
- break;
-
- case PSN_INFOCHANGED:
- CIcqProto * ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- if (!ppro)
- break;
-
- char* szProto;
- MCONTACT hContact = (MCONTACT)((LPPSHNOTIFY)lParam)->lParam;
-
- if (hContact == NULL)
- szProto = ppro->m_szModuleName;
- else
- szProto = GetContactProto(hContact);
-
- if (!szProto)
- break;
-
- SetValue(ppro, hwndDlg, IDC_UIN, hContact, szProto, UNIQUEIDSETTING, SVS_NORMAL);
- SetValue(ppro, hwndDlg, IDC_ONLINESINCE, hContact, szProto, "LogonTS", SVS_TIMESTAMP);
- SetValue(ppro, hwndDlg, IDC_IDLETIME, hContact, szProto, "IdleTS", SVS_TIMESTAMP);
- SetValue(ppro, hwndDlg, IDC_IP, hContact, szProto, "IP", SVS_IP);
- SetValue(ppro, hwndDlg, IDC_REALIP, hContact, szProto, "RealIP", SVS_IP);
-
- if (hContact) {
- SetValue(ppro, hwndDlg, IDC_PORT, hContact, szProto, "UserPort", SVS_ZEROISUNSPEC);
- SetValue(ppro, hwndDlg, IDC_VERSION, hContact, szProto, "Version", SVS_ICQVERSION);
- SetValue(ppro, hwndDlg, IDC_MIRVER, hContact, szProto, "MirVer", SVS_ZEROISUNSPEC);
- if (ppro->getByte(hContact, "ClientID", 0))
- ppro->setDword(hContact, "TickTS", 0);
- SetValue(ppro, hwndDlg, IDC_SYSTEMUPTIME, hContact, szProto, "TickTS", SVS_TIMESTAMP);
- SetValue(ppro, hwndDlg, IDC_STATUS, hContact, szProto, "Status", SVS_STATUSID);
- }
- else {
- MFileVersion v;
- Miranda_GetFileVersion(&v);
-
- char str[MAX_PATH];
- mir_snprintf(str, "Miranda NG %d.%d.%d.%d (ICQ %s)", v[0], v[1], v[2], v[3], __VERSION_STRING_DOTS);
-
- SetValue(ppro, hwndDlg, IDC_PORT, hContact, (char*)DBVT_WORD, (char*)ppro->wListenPort, SVS_ZEROISUNSPEC);
- SetValue(ppro, hwndDlg, IDC_VERSION, hContact, (char*)DBVT_WORD, (char*)ICQ_VERSION, SVS_ICQVERSION);
- SetValue(ppro, hwndDlg, IDC_MIRVER, hContact, (char*)DBVT_ASCIIZ, str, SVS_ZEROISUNSPEC);
- SetDlgItemText(hwndDlg, IDC_SUPTIME, TranslateT("Member since:"));
- SetValue(ppro, hwndDlg, IDC_SYSTEMUPTIME, hContact, szProto, "MemberTS", SVS_TIMESTAMP);
- SetValue(ppro, hwndDlg, IDC_STATUS, hContact, (char*)DBVT_WORD, (char*)ppro->m_iStatus, SVS_STATUSID);
- }
- }
- }
- break;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDCANCEL:
- SendMessage(GetParent(hwndDlg), msg, wParam, lParam);
- break;
- }
- break;
- }
-
- return FALSE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CIcqProto::OnUserInfoInit(WPARAM wParam, LPARAM lParam)
-{
- if ((!IsICQContact(lParam)) && lParam)
- return 0;
-
- OPTIONSDIALOGPAGE odp = {};
- odp.flags = ODPF_UNICODE | ODPF_USERINFOTAB | ODPF_DONTTRANSLATE;
- odp.dwInitParam = LPARAM(this);
- odp.szTitle.w = m_tszUserName;
-
- odp.pfnDlgProc = IcqDlgProc;
- odp.position = -1900000000;
- odp.szTab.w = LPGENW("Details");
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_INFO_ICQ);
- g_plugin.addUserInfo(wParam, &odp);
-
- if (!lParam) {
- odp.szTab.w = LPGENW("Account");
- odp.position = -1899999999;
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_INFO_CHANGEINFO);
- odp.pfnDlgProc = ChangeInfoDlgProc;
- g_plugin.addUserInfo(wParam, &odp);
- }
- return 0;
-}
diff --git a/protocols/IcqOscarJ/src/utilities.cpp b/protocols/IcqOscarJ/src/utilities.cpp
deleted file mode 100644
index 05d3358153..0000000000
--- a/protocols/IcqOscarJ/src/utilities.cpp
+++ /dev/null
@@ -1,1695 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-struct gateway_index
-{
- HANDLE hConn;
- DWORD dwIndex;
-};
-
-static mir_cs gatewayMutex;
-
-static gateway_index *gateways = nullptr;
-static int gatewayCount = 0;
-
-static DWORD *spammerList = nullptr;
-static int spammerListCount = 0;
-
-
-void MoveDlgItem(HWND hwndDlg, int iItem, int left, int top, int width, int height)
-{
- RECT rc;
-
- rc.left = left;
- rc.top = top;
- rc.right = left + width;
- rc.bottom = top + height;
- MapDialogRect(hwndDlg, &rc);
- MoveWindow(GetDlgItem(hwndDlg, iItem), rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE);
-}
-
-
-void EnableDlgItem(HWND hwndDlg, UINT control, int state)
-{
- EnableWindow(GetDlgItem(hwndDlg, control), state);
-}
-
-
-void ShowDlgItem(HWND hwndDlg, UINT control, int state)
-{
- ShowWindow(GetDlgItem(hwndDlg, control), state);
-}
-
-
-void icq_EnableMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state)
-{
- for (int i = 0; i < cControls; i++)
- EnableDlgItem(hwndDlg, controls[i], state);
-}
-
-
-void icq_ShowMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state)
-{
- for (int i = 0; i < cControls; i++)
- ShowDlgItem(hwndDlg, controls[i], state);
-}
-
-
-// Maps the ICQ status flag (as seen in the status change SNACS) and returns
-// a Miranda style status.
-int IcqStatusToMiranda(WORD nIcqStatus)
-{
- int nMirandaStatus;
-
- // :NOTE: The order in which the flags are compared are important!
- // I dont like this method but it works.
-
- if (nIcqStatus & ICQ_STATUSF_INVISIBLE)
- nMirandaStatus = ID_STATUS_INVISIBLE;
- else
- if (nIcqStatus & ICQ_STATUSF_DND)
- nMirandaStatus = ID_STATUS_DND;
- else
- if (nIcqStatus & ICQ_STATUSF_OCCUPIED)
- nMirandaStatus = ID_STATUS_OCCUPIED;
- else
- if (nIcqStatus & ICQ_STATUSF_NA)
- nMirandaStatus = ID_STATUS_NA;
- else
- if (nIcqStatus & ICQ_STATUSF_AWAY)
- nMirandaStatus = ID_STATUS_AWAY;
- else
- if (nIcqStatus & ICQ_STATUSF_FFC)
- nMirandaStatus = ID_STATUS_FREECHAT;
- else
- // Can be discussed, but I think 'online' is the most generic ICQ status
- nMirandaStatus = ID_STATUS_ONLINE;
-
- return nMirandaStatus;
-}
-
-WORD MirandaStatusToIcq(int nMirandaStatus)
-{
- WORD nIcqStatus;
-
- switch (nMirandaStatus) {
- case ID_STATUS_ONLINE:
- nIcqStatus = ICQ_STATUS_ONLINE;
- break;
-
- case ID_STATUS_AWAY:
- nIcqStatus = ICQ_STATUS_AWAY;
- break;
-
- case ID_STATUS_OUTTOLUNCH:
- case ID_STATUS_NA:
- nIcqStatus = ICQ_STATUS_NA;
- break;
-
- case ID_STATUS_ONTHEPHONE:
- case ID_STATUS_OCCUPIED:
- nIcqStatus = ICQ_STATUS_OCCUPIED;
- break;
-
- case ID_STATUS_DND:
- nIcqStatus = ICQ_STATUS_DND;
- break;
-
- case ID_STATUS_INVISIBLE:
- nIcqStatus = ICQ_STATUS_INVISIBLE;
- break;
-
- case ID_STATUS_FREECHAT:
- nIcqStatus = ICQ_STATUS_FFC;
- break;
-
- case ID_STATUS_OFFLINE:
- // Oscar doesnt have anything that maps to this status. This should never happen.
- _ASSERTE(nMirandaStatus != ID_STATUS_OFFLINE);
- nIcqStatus = 0;
- break;
-
- default:
- // Online seems to be a good default.
- // Since it cant be offline, it must be a new type of online status.
- nIcqStatus = ICQ_STATUS_ONLINE;
- break;
- }
-
- return nIcqStatus;
-}
-
-int MirandaStatusToSupported(int nMirandaStatus)
-{
- int nSupportedStatus;
-
- switch (nMirandaStatus) {
-
- // These status mode does not need any mapping
- case ID_STATUS_ONLINE:
- case ID_STATUS_AWAY:
- case ID_STATUS_NA:
- case ID_STATUS_OCCUPIED:
- case ID_STATUS_DND:
- case ID_STATUS_INVISIBLE:
- case ID_STATUS_OFFLINE:
- nSupportedStatus = nMirandaStatus;
- break;
-
- case ID_STATUS_FREECHAT:
- nSupportedStatus = ID_STATUS_ONLINE;
- break;
-
- // This mode is not support and must be mapped to something else
- case ID_STATUS_OUTTOLUNCH:
- nSupportedStatus = ID_STATUS_NA;
- break;
-
- // This mode is not support and must be mapped to something else
- case ID_STATUS_ONTHEPHONE:
- nSupportedStatus = ID_STATUS_OCCUPIED;
- break;
-
- // This is not supposed to happen.
- default:
- _ASSERTE(0);
- // Online seems to be a good default.
- nSupportedStatus = ID_STATUS_ONLINE;
- break;
- }
-
- return nSupportedStatus;
-}
-
-char* MirandaStatusToStringUtf(int mirandaStatus)
-{ // return miranda status description in utf-8, use unicode service is possible
- return make_utf8_string(Clist_GetStatusModeDescription(mirandaStatus, 0));
-}
-
-char** CIcqProto::MirandaStatusToAwayMsg(int nStatus)
-{
- switch (nStatus) {
- case ID_STATUS_ONLINE:
- return &m_modeMsgs.szOnline;
-
- case ID_STATUS_AWAY:
- return &m_modeMsgs.szAway;
-
- case ID_STATUS_NA:
- return &m_modeMsgs.szNa;
-
- case ID_STATUS_OCCUPIED:
- return &m_modeMsgs.szOccupied;
-
- case ID_STATUS_DND:
- return &m_modeMsgs.szDnd;
-
- case ID_STATUS_FREECHAT:
- return &m_modeMsgs.szFfc;
-
- default:
- return nullptr;
- }
-}
-
-int AwayMsgTypeToStatus(int nMsgType)
-{
- switch (nMsgType) {
- case MTYPE_AUTOONLINE:
- return ID_STATUS_ONLINE;
-
- case MTYPE_AUTOAWAY:
- return ID_STATUS_AWAY;
-
- case MTYPE_AUTOBUSY:
- return ID_STATUS_OCCUPIED;
-
- case MTYPE_AUTONA:
- return ID_STATUS_NA;
-
- case MTYPE_AUTODND:
- return ID_STATUS_DND;
-
- case MTYPE_AUTOFFC:
- return ID_STATUS_FREECHAT;
-
- default:
- return ID_STATUS_OFFLINE;
- }
-}
-
-
-void SetGatewayIndex(HANDLE hConn, DWORD dwIndex)
-{
- mir_cslock l(gatewayMutex);
-
- for (int i = 0; i < gatewayCount; i++) {
- if (hConn == gateways[i].hConn) {
- gateways[i].dwIndex = dwIndex;
- return;
- }
- }
-
- gateways = (gateway_index *)SAFE_REALLOC(gateways, sizeof(gateway_index)* (gatewayCount + 1));
- gateways[gatewayCount].hConn = hConn;
- gateways[gatewayCount].dwIndex = dwIndex;
- gatewayCount++;
-}
-
-
-DWORD GetGatewayIndex(HANDLE hConn)
-{
- mir_cslock l(gatewayMutex);
-
- for (int i = 0; i < gatewayCount; i++)
- if (hConn == gateways[i].hConn)
- return gateways[i].dwIndex;
-
- return 1; // this is default
-}
-
-
-void FreeGatewayIndex(HANDLE hConn)
-{
- mir_cslock l(gatewayMutex);
-
- for (int i = 0; i < gatewayCount; i++) {
- if (hConn == gateways[i].hConn) {
- gatewayCount--;
- memmove(&gateways[i], &gateways[i + 1], sizeof(gateway_index)* (gatewayCount - i));
- gateways = (gateway_index*)SAFE_REALLOC(gateways, sizeof(gateway_index)* gatewayCount);
-
- // Gateway found, exit loop
- break;
- }
- }
-}
-
-
-void CIcqProto::AddToSpammerList(DWORD dwUIN)
-{
- mir_cslock l(gatewayMutex);
-
- spammerList = (DWORD *)SAFE_REALLOC(spammerList, sizeof(DWORD)* (spammerListCount + 1));
- spammerList[spammerListCount] = dwUIN;
- spammerListCount++;
-}
-
-
-BOOL CIcqProto::IsOnSpammerList(DWORD dwUIN)
-{
- mir_cslock l(gatewayMutex);
-
- for (int i = 0; i < spammerListCount; i++)
- if (dwUIN == spammerList[i])
- return TRUE;
-
- return FALSE;
-}
-
-
-// ICQ contacts cache
-
-void CIcqProto::AddToContactsCache(MCONTACT hContact, DWORD dwUin, const char *szUid)
-{
- if (!hContact || (!dwUin && !szUid))
- return;
-
- icq_contacts_cache *cache_item = (icq_contacts_cache*)SAFE_MALLOC(sizeof(icq_contacts_cache));
- cache_item->hContact = hContact;
- cache_item->dwUin = dwUin;
- if (!dwUin)
- cache_item->szUid = null_strdup(szUid);
-
- mir_cslock l(contactsCacheMutex);
- contactsCache.insert(cache_item);
-}
-
-
-void CIcqProto::InitContactsCache()
-{
- // build cache
- mir_cslock l(contactsCacheMutex);
-
- for (auto &hContact : AccContacts()) {
- DWORD dwUin;
- uid_str szUid;
- if (!getContactUid(hContact, &dwUin, &szUid))
- AddToContactsCache(hContact, dwUin, szUid);
- }
-}
-
-
-void CIcqProto::UninitContactsCache(void)
-{
- mir_cslock l(contactsCacheMutex);
-
- // cleanup the cache
- for (auto &it : contactsCache) {
- SAFE_FREE((void**)&it->szUid);
- SAFE_FREE((void**)&it);
- }
-
- contactsCache.destroy();
-}
-
-
-void CIcqProto::DeleteFromContactsCache(MCONTACT hContact)
-{
- mir_cslock l(contactsCacheMutex);
-
- for (auto &it : contactsCache) {
- if (it->hContact == hContact) {
- // Release memory
- SAFE_FREE((void**)&it->szUid);
- SAFE_FREE((void**)&it);
- contactsCache.removeItem(&it);
- break;
- }
- }
-}
-
-
-MCONTACT CIcqProto::HandleFromCacheByUid(DWORD dwUin, const char *szUid)
-{
- icq_contacts_cache cache_item = { NULL, dwUin, szUid };
-
- mir_cslock l(contactsCacheMutex);
- // find in list
- int i = contactsCache.getIndex(&cache_item);
- if (i != -1)
- return contactsCache[i]->hContact;
-
- return NULL;
-}
-
-
-MCONTACT CIcqProto::HContactFromUIN(DWORD dwUin, int *Added)
-{
- if (Added)
- *Added = 0;
-
- MCONTACT cc = HandleFromCacheByUid(dwUin, nullptr);
- if (cc)
- return cc;
-
- for (auto &hContact : AccContacts()) {
- DWORD dwContactUin = getContactUin(hContact);
- if (dwContactUin == dwUin) {
- AddToContactsCache(hContact, dwUin, nullptr);
- return hContact;
- }
- }
-
- // not present: add
- if (Added) {
- debugLogA("Attempt to create ICQ contact %u", dwUin);
-
- MCONTACT hContact = db_add_contact();
- if (!hContact) {
- debugLogA("Failed to create ICQ contact %u", dwUin);
- return INVALID_CONTACT_ID;
- }
-
- if (Proto_AddToContact(hContact, m_szModuleName) != 0) {
- // For some reason we failed to register the protocol to this contact
- db_delete_contact(hContact);
- debugLogA("Failed to register ICQ contact %u", dwUin);
- return INVALID_CONTACT_ID;
- }
-
- setDword(hContact, UNIQUEIDSETTING, dwUin);
-
- if (!bIsSyncingCL) {
- db_set_b(hContact, "CList", "NotOnList", 1);
- setContactHidden(hContact, 1);
-
- setWord(hContact, "Status", ID_STATUS_OFFLINE);
-
- icq_QueueUser(hContact);
-
- if (icqOnline())
- icq_sendNewContact(dwUin, nullptr);
- }
- AddToContactsCache(hContact, dwUin, nullptr);
- *Added = 1;
- debugLogA("ICQ contact %u created ok", dwUin);
- return hContact;
- }
-
- // not in list, check that uin do not belong to us
- if (getContactUin(NULL) == dwUin)
- return NULL;
-
- return INVALID_CONTACT_ID;
-}
-
-MCONTACT CIcqProto::HContactFromUID(DWORD dwUin, const char *szUid, int *Added)
-{
- if (dwUin)
- return HContactFromUIN(dwUin, Added);
-
- if (Added)
- *Added = 0;
-
- MCONTACT cc = HandleFromCacheByUid(dwUin, szUid);
- if (cc)
- return cc;
-
- for (auto &hContact : AccContacts()) {
- DWORD dwContactUin;
- uid_str szContactUid;
- if (!getContactUid(hContact, &dwContactUin, &szContactUid)) {
- if (!dwContactUin && !mir_strcmpi(szContactUid, szUid)) {
- if (mir_strcmp(szContactUid, szUid)) // fix case in SN
- setString(hContact, UNIQUEIDSETTING, szUid);
-
- return hContact;
- }
- }
- }
-
- // not present: add
- if (Added) {
- debugLogA("Attempt to create ICQ contact by string <%s>", szUid);
-
- MCONTACT hContact = db_add_contact();
- Proto_AddToContact(hContact, m_szModuleName);
-
- setString(hContact, UNIQUEIDSETTING, szUid);
-
- if (!bIsSyncingCL) {
- db_set_b(hContact, "CList", "NotOnList", 1);
- setContactHidden(hContact, 1);
-
- setWord(hContact, "Status", ID_STATUS_OFFLINE);
-
- if (icqOnline())
- icq_sendNewContact(0, szUid);
- }
- AddToContactsCache(hContact, 0, szUid);
- *Added = 1;
- return hContact;
- }
-
- return INVALID_CONTACT_ID;
-}
-
-MCONTACT CIcqProto::HContactFromAuthEvent(MEVENT hEvent)
-{
- DWORD body[3];
-
- DBEVENTINFO dbei = {};
- dbei.cbBlob = sizeof(DWORD) * 2;
- dbei.pBlob = (PBYTE)&body;
-
- if (db_event_get(hEvent, &dbei))
- return INVALID_CONTACT_ID;
-
- if (dbei.eventType != EVENTTYPE_AUTHREQUEST)
- return INVALID_CONTACT_ID;
-
- if (mir_strcmp(dbei.szModule, m_szModuleName))
- return INVALID_CONTACT_ID;
-
- return DbGetAuthEventContact(&dbei);
-}
-
-char* NickFromHandle(MCONTACT hContact)
-{
- if (hContact == INVALID_CONTACT_ID)
- return null_strdup(Translate("<invalid>"));
-
- return null_strdup(_T2A(Clist_GetContactDisplayName(hContact)));
-}
-
-char* NickFromHandleUtf(MCONTACT hContact)
-{
- if (hContact == INVALID_CONTACT_ID)
- return ICQTranslateUtf(LPGEN("<invalid>"));
-
- return make_utf8_string(Clist_GetContactDisplayName(hContact));
-}
-
-char* strUID(DWORD dwUIN, char *pszUID)
-{
- if (dwUIN && pszUID)
- _ltoa(dwUIN, pszUID, 10);
-
- return pszUID;
-}
-
-char* __fastcall strstrnull(const char *str, const char *substr)
-{
- if (str)
- return (char*)strstr(str, substr);
-
- return nullptr;
-}
-
-char* __fastcall null_strdup(const char *string)
-{
- if (string)
- return _strdup(string);
-
- return nullptr;
-}
-
-
-WCHAR* __fastcall null_strdup(const WCHAR *string)
-{
- if (string)
- return wcsdup(string);
-
- return nullptr;
-}
-
-
-char* __fastcall null_strcpy(char *dest, const char *src, size_t maxlen)
-{
- if (!dest)
- return nullptr;
-
- if (src && src[0]) {
- strncpy(dest, src, maxlen);
- dest[maxlen] = '\0';
- }
- else
- dest[0] = '\0';
-
- return dest;
-}
-
-
-WCHAR* __fastcall null_strcpy(WCHAR *dest, const WCHAR *src, size_t maxlen)
-{
- if (!dest)
- return nullptr;
-
- if (src && src[0]) {
- wcsncpy(dest, src, maxlen);
- dest[maxlen] = '\0';
- }
- else
- dest[0] = '\0';
-
- return dest;
-}
-
-
-size_t __fastcall null_strcut(char *string, size_t maxlen)
-{ // limit the string to max length (null & utf-8 strings ready)
- size_t len = mir_strlen(string);
- if (len < maxlen)
- return len;
-
- len = maxlen;
-
- if (UTF8_IsValid(string)) // handle utf-8 string
- { // find the first byte of possible multi-byte character
- while ((string[len] & 0xc0) == 0x80) len--;
- }
-
- // simply cut the string
- string[len] = '\0';
- return len;
-}
-
-
-void parseServerAddress(char* szServer, WORD* wPort)
-{
- int i = 0;
-
- while (szServer[i] && szServer[i] != ':') i++;
- if (szServer[i] == ':') { // port included
- *wPort = atoi(&szServer[i + 1]);
- } // otherwise do not change port
-
- szServer[i] = '\0';
-}
-
-char* DemangleXml(const char *string, size_t len)
-{
- char *szWork = (char*)SAFE_MALLOC(len + 1), *szChar = szWork;
-
- for (size_t i = 0; i < len; i++) {
- if (!_strnicmp(string + i, "&gt;", 4)) {
- *szChar = '>';
- szChar++;
- i += 3;
- }
- else if (!_strnicmp(string + i, "&lt;", 4)) {
- *szChar = '<';
- szChar++;
- i += 3;
- }
- else if (!_strnicmp(string + i, "&amp;", 5)) {
- *szChar = '&';
- szChar++;
- i += 4;
- }
- else if (!_strnicmp(string + i, "&quot;", 6)) {
- *szChar = '"';
- szChar++;
- i += 5;
- }
- else {
- *szChar = string[i];
- szChar++;
- }
- }
- *szChar = '\0';
-
- return szWork;
-}
-
-char* MangleXml(const char *string, size_t len)
-{
- size_t l = 1;
- char *szWork, *szChar;
-
- for (size_t i = 0; i < len; i++) {
- if (string[i] == '<' || string[i] == '>')
- l += 4;
- else if (string[i] == '&')
- l += 5;
- else if (string[i] == '"')
- l += 6;
- else l++;
- }
- szChar = szWork = (char*)SAFE_MALLOC(l + 1);
- for (size_t i = 0; i < len; i++) {
- if (string[i] == '<') {
- *(DWORD*)szChar = ';tl&';
- szChar += 4;
- }
- else if (string[i] == '>') {
- *(DWORD*)szChar = ';tg&';
- szChar += 4;
- }
- else if (string[i] == '&') {
- *(DWORD*)szChar = 'pma&';
- szChar += 4;
- *szChar = ';';
- szChar++;
- }
- else if (string[i] == '"') {
- *(DWORD*)szChar = 'ouq&';
- szChar += 4;
- *(WORD*)szChar = ';t';
- szChar += 2;
- }
- else {
- *szChar = string[i];
- szChar++;
- }
- }
- *szChar = '\0';
-
- return szWork;
-}
-
-char* EliminateHtml(const char *string, size_t len)
-{
- char *tmp = (char*)SAFE_MALLOC(len + 1);
- BOOL tag = FALSE;
- char *res;
-
- for (size_t i = 0, j = 0; i < len; i++) {
- if (!tag && string[i] == '<') {
- if ((i + 4 <= len) && (!_strnicmp(string + i, "<br>", 4) || !_strnicmp(string + i, "<br/>", 5))) { // insert newline
- tmp[j] = '\r';
- j++;
- tmp[j] = '\n';
- j++;
- }
- tag = TRUE;
- }
- else if (tag && string[i] == '>') {
- tag = FALSE;
- }
- else if (!tag) {
- tmp[j] = string[i];
- j++;
- }
- tmp[j] = '\0';
- }
- SAFE_FREE((void**)&string);
- res = DemangleXml(tmp, mir_strlen(tmp));
- SAFE_FREE((void**)&tmp);
-
- return res;
-}
-
-char* ApplyEncoding(const char *string, const char *pszEncoding)
-{
- // decode encoding to Utf-8
- if (string && pszEncoding) { // we do only encodings known to icq5.1 // TODO: check if this is enough
- if (!_strnicmp(pszEncoding, "utf-8", 5)) // it is utf-8 encoded
- return null_strdup(string);
-
- if (!_strnicmp(pszEncoding, "unicode-2-0", 11)) { // it is UCS-2 encoded
- size_t wLen = mir_wstrlen((WCHAR*)string) + 1;
- WCHAR *szStr = (WCHAR*)_alloca(wLen * 2);
- BYTE *tmp = (BYTE*)string;
-
- unpackWideString(&tmp, szStr, wLen * 2);
-
- return make_utf8_string(szStr);
- }
- if (!_strnicmp(pszEncoding, "iso-8859-1", 10)) // we use "Latin I" instead - it does the job
- return ansi_to_utf8_codepage(string, 1252);
- }
- if (string) // consider it CP_ACP
- return ansi_to_utf8(string);
-
- return nullptr;
-}
-
-void CIcqProto::ResetSettingsOnListReload()
-{
- // Reset a bunch of session specific settings
- setWord(DBSETTING_SERVLIST_PRIVACY, 0);
- setWord(DBSETTING_SERVLIST_METAINFO, 0);
- setWord(DBSETTING_SERVLIST_AVATAR, 0);
- setWord(DBSETTING_SERVLIST_PHOTO, 0);
- setWord("SrvRecordCount", 0);
- delSetting(DBSETTING_SERVLIST_UNHANDLED);
-
- for (auto &hContact : AccContacts()) {
- // All these values will be restored during the serv-list receive
- setWord(hContact, DBSETTING_SERVLIST_ID, 0);
- setWord(hContact, DBSETTING_SERVLIST_GROUP, 0);
- setWord(hContact, DBSETTING_SERVLIST_PERMIT, 0);
- setWord(hContact, DBSETTING_SERVLIST_DENY, 0);
- delSetting(hContact, DBSETTING_SERVLIST_IGNORE);
- setByte(hContact, "Auth", 0);
- delSetting(hContact, DBSETTING_SERVLIST_DATA);
- }
-
- FlushSrvGroupsCache();
-}
-
-void CIcqProto::ResetSettingsOnConnect()
-{
- // Reset a bunch of session specific settings
- setByte("SrvVisibility", 0);
- setDword("IdleTS", 0);
-
- for (auto &hContact : AccContacts()) {
- setDword(hContact, "LogonTS", 0);
- setDword(hContact, "IdleTS", 0);
- setDword(hContact, "TickTS", 0);
- setByte(hContact, "TemporaryVisible", 0);
-
- // All these values will be restored during the login
- if (getContactStatus(hContact) != ID_STATUS_OFFLINE)
- setWord(hContact, "Status", ID_STATUS_OFFLINE);
- }
-}
-
-void CIcqProto::ResetSettingsOnLoad()
-{
- setDword("IdleTS", 0);
- setDword("LogonTS", 0);
-
- for (auto &hContact : AccContacts()) {
- setDword(hContact, "LogonTS", 0);
- setDword(hContact, "IdleTS", 0);
- setDword(hContact, "TickTS", 0);
- if (getContactStatus(hContact) != ID_STATUS_OFFLINE) {
- setWord(hContact, "Status", ID_STATUS_OFFLINE);
-
- delSetting(hContact, DBSETTING_XSTATUS_ID);
- delSetting(hContact, DBSETTING_XSTATUS_NAME);
- delSetting(hContact, DBSETTING_XSTATUS_MSG);
- }
- setByte(hContact, "DCStatus", 0);
- }
-}
-
-int RandRange(int nLow, int nHigh)
-{
- return nLow + (int)((nHigh - nLow + 1)*rand() / (RAND_MAX + 1.0));
-}
-
-
-bool IsStringUIN(const char *pszString)
-{
- size_t nLen = mir_strlen(pszString);
-
- if (nLen > 0 && pszString[0] != '0') {
- for (size_t i = 0; i < nLen; i++)
- if ((pszString[i] < '0') || (pszString[i] > '9'))
- return FALSE;
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-void __cdecl CIcqProto::ProtocolAckThread(icq_ack_args* pArguments)
-{
- Thread_SetName("ICQ: ProtocolAckThread");
- Sleep(150);
-
- if (pArguments->nAckResult == ACKRESULT_SUCCESS)
- debugLogA("Sent fake message ack");
- else if (pArguments->nAckResult == ACKRESULT_FAILED)
- debugLogA("Message delivery failed");
-
- ProtoBroadcastAck(pArguments->hContact, pArguments->nAckType, pArguments->nAckResult, pArguments->hSequence, pArguments->pszMessage);
-
- SAFE_FREE((void**)(char **)&pArguments->pszMessage);
- SAFE_FREE((void**)&pArguments);
-}
-
-void CIcqProto::SendProtoAck(MCONTACT hContact, DWORD dwCookie, int nAckResult, int nAckType, char* pszMessage)
-{
- icq_ack_args* pArgs = (icq_ack_args*)SAFE_MALLOC(sizeof(icq_ack_args)); // This will be freed in the new thread
- pArgs->hContact = hContact;
- pArgs->hSequence = (HANDLE)dwCookie;
- pArgs->nAckResult = nAckResult;
- pArgs->nAckType = nAckType;
- pArgs->pszMessage = (LPARAM)null_strdup(pszMessage);
-
- ForkThread((MyThreadFunc)&CIcqProto::ProtocolAckThread, pArgs);
-}
-
-void CIcqProto::SetCurrentStatus(int nStatus)
-{
- int nOldStatus = m_iStatus;
-
- m_iStatus = nStatus;
- ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)nOldStatus, nStatus);
-}
-
-
-int CIcqProto::IsMetaInfoChanged(MCONTACT hContact)
-{
- DBVARIANT infoToken = { DBVT_DELETED };
- int res = 0;
-
- if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &infoToken)) { // contact does have info from directory, check if it is not outdated
- double dInfoTime = 0;
- double dInfoSaved = 0;
-
- if ((dInfoTime = getSettingDouble(hContact, DBSETTING_METAINFO_TIME, 0)) > 0) {
- if ((dInfoSaved = getSettingDouble(hContact, DBSETTING_METAINFO_SAVED, 0)) > 0) {
- if (dInfoSaved < dInfoTime)
- res = 2; // directory info outdated
- }
- else
- res = 1; // directory info not saved at all
- }
-
- db_free(&infoToken);
- }
- else { // it cannot be detected if user info was not changed, so use a generic threshold
- DBVARIANT infoSaved = { DBVT_DELETED };
- DWORD dwInfoTime = 0;
-
- if (!getSetting(hContact, DBSETTING_METAINFO_SAVED, &infoSaved)) {
- if (infoSaved.type == DBVT_BLOB && infoSaved.cpbVal == 8) {
- double dwTime = *(double*)infoSaved.pbVal;
-
- dwInfoTime = (dwTime - 25567) * 86400;
- }
- else if (infoSaved.type == DBVT_DWORD)
- dwInfoTime = infoSaved.dVal;
-
- db_free(&infoSaved);
-
- if ((time(0) - dwInfoTime) > 14 * 3600 * 24) {
- res = 3; // threshold exceeded
- }
- }
- else res = 4; // no timestamp found
- }
-
- return res;
-}
-
-
-void __cdecl CIcqProto::SetStatusNoteThread(void *pDelay)
-{
- Thread_SetName("ICQ: SetStatusNoteThread");
- if (pDelay)
- SleepEx((UINT_PTR)pDelay, TRUE);
-
- mir_cslockfull l(cookieMutex);
-
- if (icqOnline() && (setStatusNoteText || setStatusMoodData)) { // send status note change packets, write status note to database
- if (setStatusNoteText) { // change status note in directory
- mir_cslockfull rlck(m_ratesMutex);
- if (m_rates) { // rate management
- WORD wGroup = m_rates->getGroupFromSNAC(ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST);
-
- while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_LIMIT)) { // we are over rate, need to wait before sending
- int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_10);
-
- rlck.unlock();
- l.unlock();
-
- debugLogA("Rates: SetStatusNote delayed %dms", nDelay);
-
- SleepEx(nDelay, TRUE); // do not keep things locked during sleep
- l.lock();
- rlck.lock();
- if (!m_rates) // we lost connection when we slept, go away
- break;
- }
- }
- rlck.unlock();
-
- BYTE *pBuffer = nullptr;
- size_t cbBuffer = 0;
-
- ppackTLV(&pBuffer, &cbBuffer, 0x226, mir_strlen(setStatusNoteText), (BYTE*)setStatusNoteText);
- icq_changeUserDirectoryInfoServ(pBuffer, cbBuffer, DIRECTORYREQUEST_UPDATENOTE);
-
- SAFE_FREE((void**)&pBuffer);
- }
-
- if (setStatusNoteText || setStatusMoodData) { // change status note and mood in session data
- mir_cslockfull rlck(m_ratesMutex);
- if (m_rates) { // rate management
- WORD wGroup = m_rates->getGroupFromSNAC(ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS);
-
- while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_LIMIT)) { // we are over rate, need to wait before sending
- int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_10);
-
- rlck.unlock();
- l.unlock();
-
- debugLogA("Rates: SetStatusNote delayed %dms", nDelay);
-
- SleepEx(nDelay, TRUE); // do not keep things locked during sleep
- l.lock();
- rlck.lock();
- if (!m_rates) // we lost connection when we slept, go away
- break;
- }
- }
- rlck.unlock();
-
- // check if the session data were not updated already
- char *szCurrentStatusNote = getSettingStringUtf(NULL, DBSETTING_STATUS_NOTE, nullptr);
- char *szCurrentStatusMood = nullptr;
- DBVARIANT dbv = { DBVT_DELETED };
-
- if (m_bMoodsEnabled && !getString(DBSETTING_STATUS_MOOD, &dbv))
- szCurrentStatusMood = dbv.pszVal;
-
- if (!setStatusNoteText && szCurrentStatusNote)
- setStatusNoteText = null_strdup(szCurrentStatusNote);
- if (m_bMoodsEnabled && !setStatusMoodData && szCurrentStatusMood)
- setStatusMoodData = null_strdup(szCurrentStatusMood);
-
- if (mir_strcmp(szCurrentStatusNote, setStatusNoteText) || (m_bMoodsEnabled && mir_strcmp(szCurrentStatusMood, setStatusMoodData))) {
- db_set_utf(NULL, m_szModuleName, DBSETTING_STATUS_NOTE, setStatusNoteText);
- if (m_bMoodsEnabled)
- setString(DBSETTING_STATUS_MOOD, setStatusMoodData);
-
- size_t wStatusNoteLen = mir_strlen(setStatusNoteText);
- size_t wStatusMoodLen = m_bMoodsEnabled ? mir_strlen(setStatusMoodData) : 0;
- size_t wDataLen = (wStatusNoteLen ? wStatusNoteLen + 4 : 0) + 4 + wStatusMoodLen + 4;
-
- icq_packet packet;
- serverPacketInit(&packet, wDataLen + 14);
- packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS);
- // Change only session data
- packWord(&packet, 0x1D); // TLV 1D
- packWord(&packet, WORD(wDataLen)); // TLV length
- packWord(&packet, 0x02); // Item Type
- if (wStatusNoteLen) {
- packWord(&packet, 0x400 | WORD(wStatusNoteLen + 4)); // Flags + Item Length
- packWord(&packet, WORD(wStatusNoteLen)); // Text Length
- packBuffer(&packet, (LPBYTE)setStatusNoteText, wStatusNoteLen);
- packWord(&packet, 0); // Encoding not specified (utf-8 is default)
- }
- else packWord(&packet, 0); // Flags + Item Length
-
- packWord(&packet, 0x0E); // Item Type
- packWord(&packet, WORD(wStatusMoodLen)); // Flags + Item Length
- if (wStatusMoodLen)
- packBuffer(&packet, (LPBYTE)setStatusMoodData, wStatusMoodLen); // Mood
-
- sendServPacket(&packet);
- }
- SAFE_FREE(&szCurrentStatusNote);
- db_free(&dbv);
- }
- }
- SAFE_FREE(&setStatusNoteText);
- SAFE_FREE(&setStatusMoodData);
-}
-
-
-int CIcqProto::SetStatusNote(const char *szStatusNote, DWORD dwDelay, int bForce)
-{
- int bChanged = FALSE;
-
- // bForce is intended for login sequence - need to call this earlier than icqOnline()
- // the process is delayed and icqOnline() is ready when needed inside SetStatusNoteThread()
- if (!bForce && !icqOnline()) return bChanged;
-
- // reuse generic critical section (used for cookies list and object variables locks)
- mir_cslock l(cookieMutex);
-
- if (!setStatusNoteText && (!m_bMoodsEnabled || !setStatusMoodData)) { // check if the status note was changed and if yes, create thread to change it
- char *szCurrentStatusNote = getSettingStringUtf(NULL, DBSETTING_STATUS_NOTE, nullptr);
-
- if (mir_strcmp(szCurrentStatusNote, szStatusNote)) { // status note was changed
- // create thread to change status note on existing server connection
- setStatusNoteText = null_strdup(szStatusNote);
-
- if (dwDelay)
- ForkThread(&CIcqProto::SetStatusNoteThread, (void*)dwDelay);
- else // we cannot afford any delay, so do not run in separate thread
- SetStatusNoteThread(nullptr);
-
- bChanged = TRUE;
- }
- SAFE_FREE(&szCurrentStatusNote);
- }
- else { // only alter status note object with new status note, keep the thread waiting for execution
- SAFE_FREE(&setStatusNoteText);
- setStatusNoteText = null_strdup(szStatusNote);
-
- bChanged = TRUE;
- }
-
- return bChanged;
-}
-
-
-int CIcqProto::SetStatusMood(const char *szMoodData, DWORD dwDelay)
-{
- int bChanged = FALSE;
-
- if (!icqOnline()) return bChanged;
-
- // reuse generic critical section (used for cookies list and object variables locks)
- mir_cslock l(cookieMutex);
-
- if (!setStatusNoteText && !setStatusMoodData) { // check if the status mood was changed and if yes, create thread to change it
- char *szCurrentStatusMood = nullptr;
- DBVARIANT dbv = { DBVT_DELETED };
-
- if (!getString(DBSETTING_STATUS_MOOD, &dbv))
- szCurrentStatusMood = dbv.pszVal;
-
- if (mir_strcmp(szCurrentStatusMood, szMoodData)) { // status mood was changed
- // create thread to change status mood on existing server connection
- setStatusMoodData = null_strdup(szMoodData);
- if (dwDelay)
- ForkThread(&CIcqProto::SetStatusNoteThread, (void*)dwDelay);
- else // we cannot afford any delay, so do not run in separate thread
- SetStatusNoteThread(nullptr);
-
- bChanged = TRUE;
- }
- db_free(&dbv);
- }
- else { // only alter status mood object with new status mood, keep the thread waiting for execution
- SAFE_FREE(&setStatusMoodData);
- setStatusMoodData = null_strdup(szMoodData);
-
- bChanged = TRUE;
- }
-
- return bChanged;
-}
-
-
-void CIcqProto::writeDbInfoSettingTLVStringUtf(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv)
-{
- oscar_tlv *pTLV = chain->getTLV(wTlv, 1);
-
- if (pTLV && pTLV->wLen > 0) {
- char *str = (char*)_alloca(pTLV->wLen + 1);
-
- memcpy(str, pTLV->pData, pTLV->wLen);
- str[pTLV->wLen] = '\0';
- db_set_utf(hContact, m_szModuleName, szSetting, str);
- }
- else delSetting(hContact, szSetting);
-}
-
-
-void CIcqProto::writeDbInfoSettingTLVWord(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv)
-{
- int num = chain->getNumber(wTlv, 1);
- if (num > 0 && num != 0x7FFF)
- setWord(hContact, szSetting, num);
- else
- delSetting(hContact, szSetting);
-}
-
-
-void CIcqProto::writeDbInfoSettingTLVByte(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv)
-{
- int num = chain->getNumber(wTlv, 1);
- if (num > 0 && num != 0x7F)
- setByte(hContact, szSetting, num);
- else
- delSetting(hContact, szSetting);
-}
-
-
-void CIcqProto::writeDbInfoSettingTLVDouble(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv)
-{
- double num = chain->getDouble(wTlv, 1);
- if (num > 0)
- setSettingDouble(hContact, szSetting, num);
- else
- delSetting(hContact, szSetting);
-}
-
-void CIcqProto::writeDbInfoSettingTLVDate(MCONTACT hContact, const char* szSettingYear, const char* szSettingMonth, const char* szSettingDay, oscar_tlv_chain* chain, WORD wTlv)
-{
- double time = chain->getDouble(wTlv, 1);
-
- if (time > 0) { // date is stored as double with unit equal to a day, incrementing since 1/1/1900 0:00 GMT
- SYSTEMTIME sTime = { 0 };
- if (VariantTimeToSystemTime(time + 2, &sTime)) {
- setWord(hContact, szSettingYear, sTime.wYear);
- setByte(hContact, szSettingMonth, (BYTE)sTime.wMonth);
- setByte(hContact, szSettingDay, (BYTE)sTime.wDay);
- }
- else {
- delSetting(hContact, szSettingYear);
- delSetting(hContact, szSettingMonth);
- delSetting(hContact, szSettingDay);
- }
- }
- else {
- delSetting(hContact, szSettingYear);
- delSetting(hContact, szSettingMonth);
- delSetting(hContact, szSettingDay);
- }
-}
-
-
-void CIcqProto::writeDbInfoSettingTLVBlob(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv)
-{
- oscar_tlv *pTLV = chain->getTLV(wTlv, 1);
-
- if (pTLV && pTLV->wLen > 0)
- setSettingBlob(hContact, szSetting, pTLV->pData, pTLV->wLen);
- else
- delSetting(hContact, szSetting);
-}
-
-char* time2text(time_t time)
-{
- tm *local = localtime(&time);
-
- if (local) {
- char *str = asctime(local);
- str[24] = '\0'; // remove new line
- return str;
- }
-
- return "<invalid>";
-}
-
-
-bool CIcqProto::validateStatusMessageRequest(MCONTACT hContact, WORD byMessageType)
-{
- // Privacy control
- if (getByte("StatusMsgReplyCList", 0)) {
- // Don't send statusmessage to unknown contacts
- if (hContact == INVALID_CONTACT_ID)
- return false;
-
- // Don't send statusmessage to temporary contacts or hidden contacts
- if (db_get_b(hContact, "CList", "NotOnList", 0) ||
- db_get_b(hContact, "CList", "Hidden", 0))
- return false;
-
- // Don't send statusmessage to invisible contacts
- if (getByte("StatusMsgReplyVisible", 0)) {
- WORD wStatus = getContactStatus(hContact);
- if (wStatus == ID_STATUS_OFFLINE)
- return false;
- }
- }
-
- // Dont send messages to people you are hiding from
- if (hContact != INVALID_CONTACT_ID &&
- getWord(hContact, "ApparentMode", 0) == ID_STATUS_OFFLINE) {
- return false;
- }
-
- // Dont respond to request for other statuses than your current one
- if ((byMessageType == MTYPE_AUTOONLINE && m_iStatus != ID_STATUS_ONLINE) ||
- (byMessageType == MTYPE_AUTOAWAY && m_iStatus != ID_STATUS_AWAY) ||
- (byMessageType == MTYPE_AUTOBUSY && m_iStatus != ID_STATUS_OCCUPIED) ||
- (byMessageType == MTYPE_AUTONA && m_iStatus != ID_STATUS_NA) ||
- (byMessageType == MTYPE_AUTODND && m_iStatus != ID_STATUS_DND) ||
- (byMessageType == MTYPE_AUTOFFC && m_iStatus != ID_STATUS_FREECHAT)) {
- return false;
- }
-
- if (hContact != INVALID_CONTACT_ID && m_iStatus == ID_STATUS_INVISIBLE &&
- getWord(hContact, "ApparentMode", 0) != ID_STATUS_ONLINE) {
- if (!getByte(hContact, "TemporaryVisible", 0)) { // Allow request to temporary visible contacts
- return false;
- }
- }
-
- // All OK!
- return true;
-}
-
-void __fastcall SAFE_FREE(void** p)
-{
- if (*p) {
- free(*p);
- *p = nullptr;
- }
-}
-
-void* __fastcall SAFE_MALLOC(size_t size)
-{
- void* p = nullptr;
-
- if (size) {
- p = malloc(size);
- if (p)
- memset(p, 0, size);
- }
- return p;
-}
-
-void* __fastcall SAFE_REALLOC(void* p, size_t size)
-{
- if (p)
- return realloc(p, size);
-
- return SAFE_MALLOC(size);
-}
-
-DWORD ICQWaitForSingleObject(HANDLE hObject, DWORD dwMilliseconds, int bWaitAlways)
-{
- DWORD dwResult;
-
- // will get WAIT_IO_COMPLETION for QueueUserAPC(), ignore it unless terminating
- do {
- dwResult = WaitForSingleObjectEx(hObject, dwMilliseconds, TRUE);
- }
- while (dwResult == WAIT_IO_COMPLETION && (bWaitAlways || !Miranda_IsTerminated()));
-
- return dwResult;
-}
-
-
-HNETLIBCONN NetLib_OpenConnection(HNETLIBUSER hUser, const char* szIdent, NETLIBOPENCONNECTION* nloc)
-{
- Netlib_Logf(hUser, "%sConnecting to %s:%u", szIdent ? szIdent : "", nloc->szHost, nloc->wPort);
-
- nloc->cbSize = sizeof(NETLIBOPENCONNECTION);
- nloc->flags |= NLOCF_V2;
- return Netlib_OpenConnection(hUser, nloc);
-}
-
-
-HNETLIBBIND CIcqProto::NetLib_BindPort(NETLIBNEWCONNECTIONPROC_V2 pFunc, void* lParam, WORD* pwPort, DWORD* pdwIntIP)
-{
- NETLIBBIND nlb = {};
- nlb.pfnNewConnectionV2 = pFunc;
- nlb.pExtra = lParam;
- SetLastError(ERROR_INVALID_PARAMETER); // this must be here - NetLib does not set any error :((
-
- HNETLIBBIND hBoundPort = Netlib_BindPort(m_hDirectNetlibUser, &nlb);
-
- if (pwPort) *pwPort = nlb.wPort;
- if (pdwIntIP) *pdwIntIP = nlb.dwInternalIP;
-
- return hBoundPort;
-}
-
-
-void NetLib_CloseConnection(HNETLIBCONN *hConnection, int bServerConn)
-{
- if (*hConnection) {
- Netlib_CloseHandle(*hConnection);
- *hConnection = nullptr;
-
- if (bServerConn)
- FreeGatewayIndex(*hConnection);
- }
-}
-
-
-void NetLib_SafeCloseHandle(HANDLE *hConnection)
-{
- if (*hConnection) {
- Netlib_CloseHandle(*hConnection);
- *hConnection = nullptr;
- }
-}
-
-
-int CIcqProto::NetLog_Direct(const char *fmt, ...)
-{
- char szText[1024];
-
- va_list va;
- va_start(va, fmt);
- mir_vsnprintf(szText, sizeof(szText), fmt, va);
- va_end(va);
- return Netlib_Log(m_hDirectNetlibUser, szText);
-}
-
-int CIcqProto::NetLog_Uni(BOOL bDC, const char *fmt, ...)
-{
- char szText[1024];
- va_list va;
- va_start(va, fmt);
- mir_vsnprintf(szText, sizeof(szText), fmt, va);
- va_end(va);
-
- HNETLIBUSER hNetlib = (bDC) ? m_hDirectNetlibUser : m_hNetlibUser;
- return Netlib_Log(hNetlib, szText);
-}
-
-char* __fastcall ICQTranslateUtf(const char *src)
-{ // this takes UTF-8 strings only!!!
- char *szRes = nullptr;
-
- if (!mir_strlen(src)) { // for the case of empty strings
- return null_strdup(src);
- }
-
- { // we can use unicode translate (0.5+)
- WCHAR* usrc = make_unicode_string(src);
-
- szRes = make_utf8_string(TranslateW(usrc));
-
- SAFE_FREE((void**)&usrc);
- }
- return szRes;
-}
-
-char* __fastcall ICQTranslateUtfStatic(const char *src, char *buf, size_t bufsize)
-{ // this takes UTF-8 strings only!!!
- if (mir_strlen(src)) { // we can use unicode translate (0.5+)
- WCHAR *usrc = make_unicode_string(src);
-
- make_utf8_string_static(TranslateW(usrc), buf, bufsize);
-
- SAFE_FREE((void**)&usrc);
- }
- else
- buf[0] = '\0';
-
- return buf;
-}
-
-template<size_t cbSize>
-char* CIcqProto::GetUserStoredPassword(char(&szBuffer)[cbSize])
-{
- if (!getSettingStringStatic(NULL, "Password", szBuffer, cbSize))
- if (mir_strlen(szBuffer))
- return szBuffer;
-
- return nullptr;
-}
-
-
-char* CIcqProto::GetUserPassword(BOOL bAlways)
-{
- if (m_szPassword[0] != '\0' && (m_bRememberPwd || bAlways))
- return m_szPassword;
-
- if (GetUserStoredPassword(m_szPassword)) {
- m_bRememberPwd = true;
- return m_szPassword;
- }
-
- return nullptr;
-}
-
-
-WORD CIcqProto::GetMyStatusFlags()
-{
- WORD wFlags = 0;
-
- // Webaware setting bit flag
- if (getByte("WebAware", 0))
- wFlags |= STATUS_WEBAWARE;
-
- // DC setting bit flag
- switch (getByte("DCType", 0)) {
- case 0:
- break;
-
- case 1:
- wFlags |= STATUS_DCCONT;
- break;
-
- case 2:
- wFlags |= STATUS_DCAUTH;
- break;
-
- default:
- wFlags |= STATUS_DCDISABLED;
- break;
- }
- return wFlags;
-}
-
-
-int IsValidRelativePath(const char *filename)
-{
- if (strstrnull(filename, "..\\") || strstrnull(filename, "../") ||
- strstrnull(filename, ":\\") || strstrnull(filename, ":/") ||
- filename[0] == '\\' || filename[0] == '/')
- return 0; // Contains malicious chars, Failure
-
- return 1; // Success
-}
-
-
-const char* ExtractFileName(const char *fullname)
-{
- const char *szFileName;
-
- // already is only filename
- if (((szFileName = strrchr(fullname, '\\')) == nullptr) && ((szFileName = strrchr(fullname, '/')) == nullptr))
- return fullname;
-
- return szFileName + 1; // skip backslash
-}
-
-
-char* FileNameToUtf(const wchar_t *filename)
-{
- WCHAR *usFileName = nullptr;
- int wchars = GetLongPathName(filename, usFileName, 0);
- usFileName = (WCHAR*)_alloca((wchars + 1) * sizeof(WCHAR));
- GetLongPathName(filename, usFileName, wchars);
-
- return make_utf8_string(usFileName);
-}
-
-
-int FileAccessUtf(const char *path, int mode)
-{
- size_t size = mir_strlen(path) + 2;
- wchar_t *szPath = (wchar_t*)_alloca(size * sizeof(wchar_t));
-
- if (make_unicode_string_static(path, szPath, size))
- return _waccess(szPath, mode);
-
- return -1;
-}
-
-
-int FileStatUtf(const char *path, struct _stati64 *buffer)
-{
- size_t size = mir_strlen(path) + 2;
- wchar_t *szPath = (wchar_t*)_alloca(size * sizeof(wchar_t));
-
- if (make_unicode_string_static(path, szPath, size))
- return _wstat64(szPath, buffer);
-
- return -1;
-}
-
-
-int MakeDirUtf(const char *dir)
-{
- int wRes = -1;
- size_t size = mir_strlen(dir) + 2;
- wchar_t *szDir = (wchar_t*)_alloca(size * sizeof(wchar_t));
-
- if (make_unicode_string_static(dir, szDir, size)) { // _wmkdir can created only one dir at once
- wRes = _wmkdir(szDir);
- // check if dir not already existed - return success if yes
- if (wRes == -1 && errno == 17 /* EEXIST */)
- wRes = 0;
- else if (wRes && errno == 2 /* ENOENT */) { // failed, try one directory less first
- char *szLast = (char*)strrchr(dir, '\\');
- if (!szLast) szLast = (char*)strrchr(dir, '/');
- if (szLast) {
- char cOld = *szLast;
-
- *szLast = '\0';
- if (!MakeDirUtf(dir))
- wRes = _wmkdir(szDir);
-
- *szLast = cOld;
- }
- }
- }
-
- return wRes;
-}
-
-
-int OpenFileUtf(const char *filename, int oflag, int pmode)
-{
- size_t size = mir_strlen(filename) + 2;
- wchar_t *szFile = (wchar_t*)_alloca(size * sizeof(wchar_t));
-
- if (make_unicode_string_static(filename, szFile, size))
- return _wopen(szFile, oflag, pmode);
-
- return -1;
-}
-
-
-WCHAR *GetWindowTextUcs(HWND hWnd)
-{
- int nLen = GetWindowTextLengthW(hWnd);
- WCHAR *utext = (WCHAR*)SAFE_MALLOC((nLen + 2) * sizeof(WCHAR));
- GetWindowTextW(hWnd, utext, nLen + 1);
- return utext;
-}
-
-
-void SetWindowTextUcs(HWND hWnd, WCHAR *text)
-{
- SetWindowTextW(hWnd, text);
-}
-
-
-char* GetWindowTextUtf(HWND hWnd)
-{
- int nLen = GetWindowTextLength(hWnd);
- wchar_t *szText = (wchar_t*)_alloca((nLen + 2) * sizeof(wchar_t));
-
- GetWindowText(hWnd, szText, nLen + 1);
-
- return make_utf8_string(szText);
-}
-
-
-char* GetDlgItemTextUtf(HWND hwndDlg, int iItem)
-{
- return GetWindowTextUtf(GetDlgItem(hwndDlg, iItem));
-}
-
-
-void SetWindowTextUtf(HWND hWnd, const char *szText)
-{
- size_t size = mir_strlen(szText) + 2;
- wchar_t *tszText = (wchar_t*)_alloca(size * sizeof(wchar_t));
-
- if (make_unicode_string_static(szText, tszText, size))
- SetWindowText(hWnd, tszText);
-}
-
-
-void SetDlgItemTextUtf(HWND hwndDlg, int iItem, const char *szText)
-{
- SetWindowTextUtf(GetDlgItem(hwndDlg, iItem), szText);
-}
-
-
-static int ControlAddStringUtf(HWND ctrl, DWORD msg, const char *szString)
-{
- char str[MAX_PATH];
- char *szItem = ICQTranslateUtfStatic(szString, str, MAX_PATH);
- int item = -1;
- WCHAR *wItem = make_unicode_string(szItem);
- item = SendMessage(ctrl, msg, 0, (LPARAM)wItem);
- SAFE_FREE((void**)&wItem);
- return item;
-}
-
-int ComboBoxAddStringUtf(HWND hCombo, const char *szString, DWORD data)
-{
- int item = ControlAddStringUtf(hCombo, CB_ADDSTRING, szString);
- SendMessage(hCombo, CB_SETITEMDATA, item, data);
-
- return item;
-}
-
-int ListBoxAddStringUtf(HWND hList, const char *szString)
-{
- return ControlAddStringUtf(hList, LB_ADDSTRING, szString);
-}
-
-int MessageBoxUtf(HWND hWnd, const char *szText, const char *szCaption, UINT uType)
-{
- int res;
- char str[1024];
- char cap[MAX_PATH];
- WCHAR *text = make_unicode_string(ICQTranslateUtfStatic(szText, str, 1024));
- WCHAR *caption = make_unicode_string(ICQTranslateUtfStatic(szCaption, cap, MAX_PATH));
- res = MessageBoxW(hWnd, text, caption, uType);
- SAFE_FREE((void**)&caption);
- SAFE_FREE((void**)&text);
- return res;
-}
-
-char* CIcqProto::ConvertMsgToUserSpecificAnsi(MCONTACT hContact, const char* szMsg)
-{ // this takes utf-8 encoded message
- WORD wCP = getWord(hContact, "CodePage", m_wAnsiCodepage);
- char* szAnsi = nullptr;
-
- if (wCP != CP_ACP) // convert to proper codepage
- if (!utf8_decode_codepage(szMsg, &szAnsi, wCP))
- return nullptr;
-
- return szAnsi;
-}
-
-// just broadcast generic send error with dummy cookie and return that cookie
-DWORD CIcqProto::ReportGenericSendError(MCONTACT hContact, int nType, const char* szErrorMsg)
-{
- DWORD dwCookie = GenerateCookie(0);
- SendProtoAck(hContact, dwCookie, ACKRESULT_FAILED, nType, Translate(szErrorMsg));
- return dwCookie;
-}
diff --git a/protocols/IcqOscarJ/src/utilities.h b/protocols/IcqOscarJ/src/utilities.h
deleted file mode 100644
index 2146d99a62..0000000000
--- a/protocols/IcqOscarJ/src/utilities.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2018 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#ifndef __UTILITIES_H
-#define __UTILITIES_H
-
-struct icq_ack_args
-{
- MCONTACT hContact;
- int nAckType;
- int nAckResult;
- HANDLE hSequence;
- LPARAM pszMessage;
-};
-
-struct icq_contacts_cache
-{
- MCONTACT hContact;
- DWORD dwUin;
- const char *szUid;
-};
-
-
-/*---------* Functions *---------------*/
-
-void MoveDlgItem(HWND hwndDlg, int iItem, int left, int top, int width, int height);
-void EnableDlgItem(HWND hwndDlg, UINT control, int state);
-void ShowDlgItem(HWND hwndDlg, UINT control, int state);
-void icq_EnableMultipleControls(HWND hwndDlg, const UINT* controls, int cControls, int state);
-void icq_ShowMultipleControls(HWND hwndDlg, const UINT* controls, int cControls, int state);
-int IcqStatusToMiranda(WORD wStatus);
-WORD MirandaStatusToIcq(int nStatus);
-int MirandaStatusToSupported(int nMirandaStatus);
-char* MirandaStatusToStringUtf(int);
-
-int AwayMsgTypeToStatus(int nMsgType);
-
-void SetGatewayIndex(HANDLE hConn, DWORD dwIndex);
-DWORD GetGatewayIndex(HANDLE hConn);
-void FreeGatewayIndex(HANDLE hConn);
-
-char* NickFromHandle(MCONTACT hContact);
-char* NickFromHandleUtf(MCONTACT hContact);
-char* strUID(DWORD dwUIN, char *pszUID);
-
-char* __fastcall strstrnull(const char *str, const char *substr);
-char* __fastcall null_strdup(const char *string);
-char* __fastcall null_strcpy(char *dest, const char *src, size_t maxlen);
-size_t __fastcall null_strcut(char *string, size_t maxlen);
-
-WCHAR* __fastcall null_strdup(const WCHAR *string);
-WCHAR* __fastcall null_strcpy(WCHAR *dest, const WCHAR *src, size_t maxlen);
-
-void parseServerAddress(char *szServer, WORD* wPort);
-
-char* DemangleXml(const char *string, size_t len);
-char* MangleXml(const char *string, size_t len);
-char* EliminateHtml(const char *string, size_t len);
-char* ApplyEncoding(const char *string, const char *pszEncoding);
-
-int RandRange(int nLow, int nHigh);
-
-bool IsStringUIN(const char *pszString);
-
-char* time2text(time_t time);
-
-void __fastcall SAFE_FREE(void** p);
-void* __fastcall SAFE_MALLOC(size_t size);
-void* __fastcall SAFE_REALLOC(void* p, size_t size);
-
-__inline static void SAFE_FREE(char** str) { SAFE_FREE((void**)str); }
-__inline static void SAFE_FREE(WCHAR** str) { SAFE_FREE((void**)str); }
-
-DWORD ICQWaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds, int bWaitAlways = FALSE);
-
-HNETLIBCONN NetLib_OpenConnection(HNETLIBUSER hUser, const char* szIdent, NETLIBOPENCONNECTION* nloc);
-void NetLib_CloseConnection(HNETLIBCONN *hConnection, int bServerConn);
-void NetLib_SafeCloseHandle(HANDLE *);
-
-char* __fastcall ICQTranslateUtf(const char *src);
-char* __fastcall ICQTranslateUtfStatic(const char *src, char *buf, size_t bufsize);
-
-WORD GetMyStatusFlags();
-
-/* Unicode FS utility functions */
-
-int IsValidRelativePath(const char *filename);
-LPCSTR ExtractFileName(const char *fullname);
-char* FileNameToUtf(const wchar_t *filename);
-
-int FileAccessUtf(const char *path, int mode);
-int FileStatUtf(const char *path, struct _stati64 *buffer);
-int MakeDirUtf(const char *dir);
-int OpenFileUtf(const char *filename, int oflag, int pmode);
-
-/* Unicode UI utility functions */
-WCHAR* GetWindowTextUcs(HWND hWnd);
-void SetWindowTextUcs(HWND hWnd, WCHAR *text);
-char* GetWindowTextUtf(HWND hWnd);
-char* GetDlgItemTextUtf(HWND hwndDlg, int iItem);
-void SetWindowTextUtf(HWND hWnd, const char *szText);
-void SetDlgItemTextUtf(HWND hwndDlg, int iItem, const char *szText);
-
-int ComboBoxAddStringUtf(HWND hCombo, const char *szString, DWORD data);
-int ListBoxAddStringUtf(HWND hList, const char *szString);
-
-int MessageBoxUtf(HWND hWnd, const char *szText, const char *szCaption, UINT uType);
-
-void InitXStatusIcons();
-void setContactExtraIcon(MCONTACT hContact, int xstatus);
-int OnReloadIcons(WPARAM wParam, LPARAM lParam);
-
-#endif /* __UTILITIES_H */
diff --git a/protocols/IcqOscarJ/src/version.h b/protocols/IcqOscarJ/src/version.h
deleted file mode 100644
index 253becb75d..0000000000
--- a/protocols/IcqOscarJ/src/version.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#define __MAJOR_VERSION 0
-#define __MINOR_VERSION 95
-#define __RELEASE_NUM 8
-#define __BUILD_NUM 1
-
-#include <stdver.h>
-
-#define __PLUGIN_NAME "IcqOscarJ protocol"
-#define __FILENAME "ICQ.dll"
-#define __DESCRIPTION "ICQ protocol support for Miranda NG."
-#define __AUTHOR "Joe Kucera, Bio, Martin Öberg, Richard Hughes, Jon Keating, etc."
-#define __AUTHORWEB "https://miranda-ng.org/p/ICQ/"
-#define __COPYRIGHT "© 2000-18 M.Öberg, R.Hughes, J.Keating, Bio, Angeli-Ka, G.Hazan, J.Kucera"