From 6d932bfaf11e4699355fedc45e28b353b8877130 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 18 Sep 2014 21:52:10 +0000 Subject: merge into trunk git-svn-id: http://svn.miranda-ng.org/main/trunk@10515 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/WhatsApp/src/WASocketConnection.h | 4 +- .../WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp | 3 - .../WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp | 1 - protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp | 6 - protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp | 1 - protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp | 297 ++++++++++++++++++++ protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h | 23 ++ .../WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp | 2 - protocols/WhatsApp/src/WhatsAPI++/WAConnection.h | 1 - protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp | 94 +++++++ protocols/WhatsApp/src/WhatsAPI++/WARegister.h | 23 ++ protocols/WhatsApp/src/WhatsAPI++/utilities.cpp | 267 ++++++++---------- protocols/WhatsApp/src/WhatsAPI++/utilities.h | 7 - protocols/WhatsApp/src/chat.cpp | 67 +++-- protocols/WhatsApp/src/common.h | 1 + protocols/WhatsApp/src/connection.cpp | 138 ++++------ protocols/WhatsApp/src/constants.h | 10 +- protocols/WhatsApp/src/contacts.cpp | 297 ++++++++------------ protocols/WhatsApp/src/definitions.h | 11 +- protocols/WhatsApp/src/dialogs.cpp | 137 ++++------ protocols/WhatsApp/src/dialogs.h | 4 +- protocols/WhatsApp/src/entities.h | 30 +- protocols/WhatsApp/src/main.cpp | 187 +------------ protocols/WhatsApp/src/messages.cpp | 81 +++--- protocols/WhatsApp/src/proto.cpp | 301 +++++++++------------ protocols/WhatsApp/src/proto.h | 260 +++++++++--------- protocols/WhatsApp/src/resource.h | 7 +- protocols/WhatsApp/src/theme.cpp | 10 +- protocols/WhatsApp/src/utils.cpp | 86 +----- protocols/WhatsApp/src/utils.h | 64 ++--- protocols/WhatsApp/src/version.h | 4 +- 31 files changed, 1163 insertions(+), 1261 deletions(-) create mode 100644 protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp create mode 100644 protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h create mode 100644 protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp create mode 100644 protocols/WhatsApp/src/WhatsAPI++/WARegister.h (limited to 'protocols/WhatsApp/src') diff --git a/protocols/WhatsApp/src/WASocketConnection.h b/protocols/WhatsApp/src/WASocketConnection.h index 53d16fd419..48c64f2a1a 100644 --- a/protocols/WhatsApp/src/WASocketConnection.h +++ b/protocols/WhatsApp/src/WASocketConnection.h @@ -11,14 +11,14 @@ class WASocketConnection : public ISocketConnection { public: - static HANDLE hNetlibUser; + static HANDLE hNetlibUser; private: int readSize; int maxBufRead; bool connected; - HANDLE hConn; + HANDLE hConn; public: WASocketConnection(const std::string& dir, int port) throw (WAException); diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp index 9da677ba87..388bf10e4a 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp @@ -342,6 +342,3 @@ int BinTreeNodeReader::readInt24(ISocketConnection* in) { return value; } - - - diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp index 2c244d53b7..6936de9a8b 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp @@ -264,4 +264,3 @@ BinTreeNodeWriter::~BinTreeNodeWriter() { if (this->out != NULL) delete this->out; } - diff --git a/protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp b/protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp index c9117bcfee..d52b10c549 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp @@ -147,9 +147,3 @@ void ByteArrayOutputStream::print() { _LOGDATA("%s", numbers.c_str()); _LOGDATA("]"); } - - - - - - diff --git a/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp b/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp index b8586eb538..0eca3aeef7 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp @@ -125,4 +125,3 @@ unsigned char FMessage::getMessage_WA_Type(std::string* type) { return WA_TYPE_UNDEFINED; } - diff --git a/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp b/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp new file mode 100644 index 0000000000..8171094d5c --- /dev/null +++ b/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp @@ -0,0 +1,297 @@ +/* + * PhoneNumber.cpp + * + */ + +#include "PhoneNumber.h" +#include "WAException.h" + +struct CountryDescr +{ + char *name; + int countryCode, mcc, mnc; + char *ISO3166, *ISO639; +} +static countries[] = +{ + { "Russia", 7, 250, 20, "RU", "ru" }, + { "Kazakhstan", 7, 401, 77, "KZ", "kk" }, + { "Afghanistan", 93, 412, 1, "AF", "ps" }, + { "Albania", 355, 276, 1, "AL", "sq" }, + { "Alberta", 1403, 302, 720, "CA", "en" }, + { "Alberta", 1780, 302, 720, "CA", "en" }, + { "Algeria", 213, 603, 1, "DZ", "ar" }, + { "Andorra", 376, 213, 3, "AD", "ca" }, + { "Angola", 244, 631, 2, "AO", "pt" }, + { "Anguilla", 1264, 365, 10, "AI", "en" }, + { "Antarctica (Australian bases)", 6721, 232, 1, "AQ", "en" }, + { "Antigua and Barbuda", 1268, 344, 50, "AG", "en" }, + { "Argentina", 54, 722, 10, "AR", "es" }, + { "Armenia", 374, 283, 10, "AM", "hy" }, + { "Aruba", 297, 363, 1, "AW", "nl" }, + { "Ascension", 247, 658, 1, "AC", "en" }, + { "Australia", 61, 505, 1, "AU", "en" }, + { "Austria", 43, 232, 3, "AT", "de" }, + { "Azerbaijan", 994, 400, 1, "AZ", "az" }, + { "Bahamas", 1242, 364, 39, "BS", "en" }, + { "Bahrain", 973, 426, 1, "BH", "ar" }, + { "Bangladesh", 880, 470, 1, "BD", "bn" }, + { "Barbados", 1246, 342, 750, "BB", "en" }, + { "Belarus", 375, 257, 1, "BY", "be" }, + { "Belgium", 32, 206, 1, "BE", "nl" }, + { "Belize", 501, 702, 67, "BZ", "es" }, + { "Benin", 229, 616, 1, "BJ", "fr" }, + { "Bermuda", 1441, 350, 1, "BM", "en" }, + { "Bhutan", 975, 402, 11, "BT", "dz" }, + { "Bolivia", 591, 736, 1, "BO", "es" }, + { "Bosnia and Herzegovina", 387, 218, 3, "BA", "bs" }, + { "Botswana", 267, 652, 4, "BW", "en" }, + { "Brazil", 55, 724, 2, "BR", "pt" }, + { "British Columbia", 1250, 302, 720, "CA", "en" }, + { "British Columbia", 1604, 302, 720, "CA", "en" }, + { "British Columbia", 1778, 302, 720, "CA", "en" }, + { "British Indian Ocean Territory", 246, 348, 1, "IO", "en" }, + { "British Virgin Islands", 1284, 348, 170, "GB", "en" }, + { "Brunei", 673, 528, 11, "BN", "ms" }, + { "Bulgaria", 359, 284, 3, "BG", "bg" }, + { "Burkina Faso", 226, 613, 1, "BF", "fr" }, + { "Burundi", 257, 642, 82, "BI", "rn" }, + { "Cambodia", 855, 456, 2, "KH", "km" }, + { "Cameroon", 237, 624, 1, "CM", "fr" }, + { "Cape Verde", 238, 625, 1, "CV", "pt" }, + { "Cayman Islands", 1345, 346, 50, "GB", "en" }, + { "Central African Republic", 236, 623, 3, "CF", "sg" }, + { "Chad", 235, 622, 4, "TD", "fr" }, + { "Chile", 56, 730, 2, "CL", "es" }, + { "China", 86, 460, 3, "CN", "en" }, + { "Colombia", 57, 732, 102, "CO", "es" }, + { "Comoros", 269, 654, 1, "KM", "fr" }, + { "Democratic Republic of the Congo", 243, 630, 1, "CD", "fr" }, + { "Republic of the Congo", 242, 629, 1, "CG", "fr" }, + { "Cook Islands", 682, 548, 1, "CK", "en" }, + { "Costa Rica", 506, 658, 4, "CR", "es" }, + { "Cote d'Ivoire", 712, 612, 1, "CI", "fr" }, + { "Croatia", 385, 219, 1, "HR", "hr" }, + { "Cuba", 53, 368, 1, "CU", "es" }, + { "Cyprus", 357, 280, 1, "CY", "el" }, + { "Czech Republic", 420, 230, 2, "CZ", "cs" }, + { "Denmark", 45, 238, 1, "DK", "da" }, + { "Djibouti", 253, 638, 1, "DJ", "fr" }, + { "Dominica", 1767, 366, 20, "DM", "en" }, + { "Dominican Republic", 1809, 370, 1, "DO", "es" }, + { "Dominican Republic", 1829, 370, 1, "DO", "en" }, + { "East Timor", 670, 514, 1, "TL", "pt" }, + { "Ecuador", 593, 740, 0, "EC", "es" }, + { "Egypt", 20, 602, 2, "EG", "ar" }, + { "El Salvador", 503, 706, 1, "SV", "es" }, + { "Equatorial Guinea", 240, 627, 3, "GQ", "es" }, + { "Eritrea", 291, 657, 1, "ER", "ti" }, + { "Estonia", 372, 248, 3, "EE", "et" }, + { "Ethiopia", 251, 636, 11, "ET", "am" }, + { "Falkland Islands", 500, 750, 1, "FK", "en" }, + { "Faroe Islands", 298, 288, 2, "FO", "fo" }, + { "Fiji", 679, 542, 1, "FJ", "en" }, + { "Finland", 358, 244, 5, "FI", "fi" }, + { "France", 33, 208, 9, "FR", "fr" }, + { "French Guiana", 594, 742, 1, "GF", "fr" }, + { "French Polynesia", 689, 547, 15, "PF", "fr" }, + { "Gabon", 241, 628, 1, "GA", "fr" }, + { "Gambia", 220, 607, 1, "GM", "en" }, + { "Gaza Strip", 970, 0, 0, "PS", "ar" }, + { "Georgia", 995, 282, 1, "GE", "ka" }, + { "Germany", 49, 262, 1, "DE", "de" }, + { "Ghana", 233, 620, 2, "GH", "ak" }, + { "Gibraltar", 350, 266, 9, "GI", "en" }, + { "Greece", 30, 202, 5, "GR", "el" }, + { "Greenland", 299, 290, 1, "GL", "kl" }, + { "Grenada", 1473, 352, 30, "GD", "en" }, + { "Guadeloupe", 590, 340, 1, "GP", "fr" }, + { "Guam", 1671, 535, 32, "GU", "en" }, + { "Guatemala", 502, 704, 1, "GT", "es" }, + { "Guinea", 224, 611, 1, "GN", "fr" }, + { "Guinea-Bissau", 245, 632, 3, "GW", "pt" }, + { "Guyana", 592, 738, 1, "GY", "pt" }, + { "Haiti", 509, 372, 2, "HT", "fr" }, + { "Honduras", 504, 708, 2, "HN", "es" }, + { "Hong Kong", 852, 454, 0, "HK", "zh" }, + { "Hungary", 36, 216, 70, "HU", "hu" }, + { "Iceland", 354, 274, 2, "IS", "is" }, + { "India", 91, 404, 30, "IN", "hi" }, + { "Indonesia", 62, 510, 10, "ID", "id" }, + { "Iraq", 964, 418, 20, "IQ", "ar" }, + { "Iran", 98, 432, 35, "IR", "fa" }, + { "Ireland (Eire)", 353, 272, 1, "IE", "en" }, + { "Israel", 972, 425, 1, "IL", "he" }, + { "Italy", 39, 222, 10, "IT", "it" }, + { "Jamaica", 1876, 338, 50, "JM", "en" }, + { "Japan", 81, 440, 1, "JP", "ja" }, + { "Jordan", 962, 416, 77, "JO", "ar" }, + { "Kenya", 254, 639, 7, "KE", "sw" }, + { "Kiribati", 686, 545, 1, "KI", "en" }, + { "Kuwait", 965, 419, 4, "KW", "ar" }, + { "Kyrgyzstan", 996, 437, 1, "KG", "ky" }, + { "Laos", 856, 457, 1, "LA", "lo" }, + { "Latvia", 371, 247, 2, "LV", "lv" }, + { "Lebanon", 961, 415, 1, "LB", "ar" }, + { "Lesotho", 266, 651, 1, "LS", "st" }, + { "Liberia", 231, 618, 7, "LR", "en" }, + { "Libya", 218, 606, 0, "LY", "ar" }, + { "Liechtenstein", 423, 295, 2, "LI", "de" }, + { "Lithuania", 370, 246, 3, "LT", "lt" }, + { "Luxembourg", 352, 270, 99, "LU", "fr" }, + { "Macau", 853, 455, 2, "MO", "pt" }, + { "Republic of Macedonia", 389, 294, 1, "MK", "mk" }, + { "Madagascar", 261, 646, 2, "MG", "mg" }, + { "Malawi", 265, 650, 1, "MW", "ny" }, + { "Malaysia", 60, 502, 16, "MY", "en" }, + { "Maldives", 960, 472, 1, "MV", "dv" }, + { "Mali", 223, 610, 2, "ML", "fr" }, + { "Malta", 356, 278, 1, "MT", "mt" }, + { "Manitoba", 1204, 302, 720, "CA", "en" }, + { "Marshall Islands", 692, 551, 1, "MH", "mh" }, + { "Martinique", 596, 340, 1, "MQ", "fr" }, + { "Mauritania", 222, 609, 2, "MR", "ar" }, + { "Mauritius", 230, 617, 1, "MU", "en" }, + { "Mayotte", 262, 654, 1, "YT", "fr" }, + { "Mexico", 52, 334, 3, "MX", "es" }, + { "Federated States of Micronesia", 691, 550, 1, "FM", "en" }, + { "Moldova", 373, 259, 1, "MD", "ru" }, + { "Monaco", 377, 212, 1, "MC", "fr" }, + { "Mongolia", 976, 428, 91, "MN", "mn" }, + { "Montenegro", 382, 297, 2, "ME", "sr" }, + { "Montserrat", 1664, 354, 860, "MS", "en" }, + { "Morocco", 212, 604, 0, "MA", "ar" }, + { "Mozambique", 258, 643, 4, "MZ", "pt" }, + { "Myanmar", 95, 414, 1, "MM", "my" }, + { "Namibia", 264, 649, 3, "NA", "en" }, + { "Nauru", 674, 536, 2, "NR", "na" }, + { "Netherlands", 31, 204, 4, "NL", "nl" }, + { "Netherlands Antilles", 599, 362, 51, "AN", "nl" }, + { "Nepal", 977, 429, 1, "NP", "ne" }, + { "New Brunswick", 1506, 302, 720, "CA", "en" }, + { "New Caledonia", 687, 546, 1, "NC", "fr" }, + { "New Zealand", 64, 530, 1, "NZ", "en" }, + { "Newfoundland", 1709, 302, 720, "CA", "en" }, + { "Nicaragua", 505, 710, 30, "NI", "es" }, + { "Niger", 227, 614, 4, "NE", "fr" }, + { "Nigeria", 234, 621, 20, "NG", "ha" }, + { "Niue", 683, 555, 1, "NU", "en" }, + { "Norfolk Island", 6723, 505, 10, "NF", "en" }, + { "North Korea", 850, 467, 193, "KP", "ko" }, + { "Northern Mariana Islands", 1670, 534, 1, "MP", "en" }, + { "Northwest Territories", 1867, 302, 720, "CA", "en" }, + { "Norway", 47, 242, 4, "NO", "nb" }, + { "Nova Scotia", 1902, 302, 720, "CA", "en" }, + { "Oman", 968, 422, 2, "OM", "ar" }, + { "Ontario", 1416, 302, 720, "CA", "en" }, + { "Ontario", 1519, 302, 720, "CA", "en" }, + { "Ontario", 1613, 302, 720, "CA", "en" }, + { "Ontario", 1647, 302, 720, "CA", "en" }, + { "Ontario", 1705, 302, 720, "CA", "en" }, + { "Ontario", 1807, 302, 720, "CA", "en" }, + { "Ontario", 1905, 302, 720, "CA", "en" }, + { "Pakistan", 92, 410, 1, "PK", "en" }, + { "Palau", 680, 552, 80, "PW", "en" }, + { "Palestine", 970, 425, 6, "PS", "ar" }, + { "Panama", 507, 714, 2, "PA", "es" }, + { "Papua New Guinea", 675, 537, 3, "PG", "ho" }, + { "Paraguay", 595, 744, 6, "PY", "es" }, + { "Peru", 51, 716, 6, "PE", "es" }, + { "Philippines", 63, 515, 2, "PH", "fil" }, + { "Poland", 48, 260, 3, "PL", "pl" }, + { "Portugal", 351, 268, 1, "PT", "pt" }, + { "Qatar", 974, 427, 2, "QA", "ar" }, + { "Quebec", 1418, 302, 720, "CA", "en" }, + { "Quebec", 1450, 302, 720, "CA", "en" }, + { "Quebec", 1514, 302, 720, "CA", "en" }, + { "Quebec", 1819, 302, 720, "CA", "en" }, + { "Reunion", 262, 647, 0, "RE", "fr" }, + { "Romania", 40, 226, 1, "RO", "ro" }, + { "Rwanda", 250, 635, 10, "RW", "rw" }, + { "Saint-Barthelemy", 590, 340, 1, "BL", "fr" }, + { "Saint Helena", 290, 658, 1, "SH", "en" }, + { "Saint Kitts and Nevis", 1869, 356, 50, "KN", "en" }, + { "Saint Lucia", 1758, 358, 50, "LC", "en" }, + { "Saint Martin (French side)", 590, 340, 1, "MF", "fr" }, + { "Saint Pierre and Miquelon", 508, 308, 2, "PM", "fr" }, + { "Saint Vincent and the Grenadines", 1670, 360, 70, "VC", "en" }, + { "Samoa", 685, 549, 1, "WS", "sm" }, + { "Sao Tome and Principe", 239, 626, 1, "ST", "pt" }, + { "Saskatchewan", 1306, 302, 720, "CA", "en" }, + { "Saudi Arabia", 966, 420, 4, "SA", "ar" }, + { "Senegal", 221, 608, 1, "SN", "wo" }, + { "Serbia", 381, 220, 1, "RS", "sr" }, + { "Seychelles", 248, 633, 10, "SC", "fr" }, + { "Sierra Leone", 232, 619, 4, "SL", "en" }, + { "Singapore", 65, 525, 1, "SG", "en" }, + { "Slovakia", 421, 231, 4, "SK", "sk" }, + { "Slovenia", 386, 293, 31, "SI", "sl" }, + { "Solomon Islands", 677, 540, 2, "SB", "en" }, + { "Somalia", 252, 637, 82, "SO", "so" }, + { "South Africa", 27, 655, 1, "ZA", "xh" }, + { "South Korea", 82, 450, 5, "KR", "ko" }, + { "South Sudan", 211, 659, 2, "SS", "en" }, + { "Spain", 34, 214, 1, "ES", "es" }, + { "Sri Lanka", 94, 413, 1, "LK", "si" }, + { "Sudan", 249, 634, 7, "SD", "ar" }, + { "Suriname", 597, 746, 3, "SR", "nl" }, + { "Swaziland", 268, 653, 10, "SZ", "ss" }, + { "Sweden", 46, 240, 7, "SE", "sv" }, + { "Switzerland", 41, 228, 3, "CH", "de" }, + { "Syria", 963, 417, 1, "SY", "ar" }, + { "Taiwan", 886, 466, 1, "TW", "cmn" }, + { "Tajikistan", 992, 436, 1, "TJ", "tg" }, + { "Tanzania", 255, 640, 4, "TZ", "sw" }, + { "Thailand", 66, 520, 0, "TH", "th" }, + { "Togo", 228, 615, 1, "TG", "fr" }, + { "Tokelau", 690, 690, 1, "TK", "tkl" }, + { "Tonga", 676, 539, 1, "TO", "to" }, + { "Trinidad and Tobago", 1868, 374, 12, "TT", "en" }, + { "Tunisia", 216, 605, 1, "TN", "ar" }, + { "Turkey", 90, 286, 2, "TR", "tr" }, + { "Turkmenistan", 993, 438, 1, "TM", "tk" }, + { "Turks and Caicos Islands", 1649, 376, 50, "TC", "en" }, + { "Tuvalu", 688, 553, 1, "TV", "tvl" }, + { "Uganda", 256, 641, 14, "UG", "sw" }, + { "Ukraine", 380, 255, 1, "UA", "uk" }, + { "United Arab Emirates", 971, 424, 2, "AE", "ar" }, + { "United Kingdom", 44, 234, 10, "GB", "en" }, + { "United States of America", 1, 310, 4, "US", "en" }, + { "Uruguay", 598, 748, 7, "UY", "es" }, + { "Uzbekistan", 998, 434, 7, "UZ", "uz" }, + { "Vanuatu", 678, 541, 5, "VU", "bi" }, + { "Venezuela", 58, 734, 4, "VE", "es" }, + { "Vietnam", 84, 452, 1, "VN", "vi" }, + { "U.S. Virgin Islands", 1340, 332, 4, "VI", "en" }, + { "Wallis and Futuna", 681, 543, 1, "WF", "fr" }, + { "West Bank", 970, 0, 1, "PS", "ar" }, + { "Yemen", 967, 421, 2, "YE", "ar" }, + { "Zambia", 260, 645, 2, "ZM", "en" }, + { "Zimbabwe", 263, 648, 2, "ZW", "en" } +}; + +PhoneNumber::PhoneNumber(const std::string &szNumber) +{ + int cc1 = atoi(szNumber.substr(0, 1).c_str()), cc2 = atoi(szNumber.substr(0, 2).c_str()), cc3 = atoi(szNumber.substr(0, 3).c_str()); + + for (int i = 0; i < _countof(countries); i++) { + CountryDescr &p = countries[i]; + if (p.countryCode != cc1 && p.countryCode != cc2 && p.countryCode != cc3) + continue; + + if (p.countryCode == 7) + if (i == 0 && (cc2 == '77' || cc2 == '76')) + continue; + + this->Country = p.name; + this->countryCode = p.countryCode; + this->Number = szNumber.substr(1 + (size_t)floor(log10(double(p.countryCode)))); + this->ISO3166 = p.ISO3166; + this->ISO639 = p.ISO639; + this->mcc = p.mcc; + this->mnc = p.mnc; + return; + } + + throw new WAException("Could not dissect phone number " + szNumber); +} diff --git a/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h b/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h new file mode 100644 index 0000000000..aa3dd16ef9 --- /dev/null +++ b/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h @@ -0,0 +1,23 @@ +/* + * PhoneNumber.h + * + */ + +#ifndef PHONENUMBER_H_ +#define PHONENUMBER_H_ + +#include + +struct PhoneNumber +{ + PhoneNumber(const std::string &number); + + std::string Country; + std::string Number; + + const char *ISO3166, *ISO639; + int countryCode; + int mcc, mnc; +}; + +#endif /* PHONENUMBER_H_ */ diff --git a/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp b/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp index be6a658acb..a44fa27812 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp @@ -131,5 +131,3 @@ void ProtocolTreeNode::require(ProtocolTreeNode *node, const string& tag) { if (!tagEquals(node, tag)) throw WAException("failed require. node:" + node->toString() + "tag: " + tag, WAException::CORRUPT_STREAM_EX, 0); } - - diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h index 9ee5d3e48f..96a813ecd0 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h @@ -462,5 +462,4 @@ class WAConnection { void sendDeleteAccount() throw(WAException); }; - #endif /* WACONNECTION_H_ */ diff --git a/protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp b/protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp new file mode 100644 index 0000000000..d67d2f4a8c --- /dev/null +++ b/protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp @@ -0,0 +1,94 @@ +/* + * WARegister.cpp + * + */ + +#include "../common.h" // #TODO Remove Miranda-dependency + +#include "WARegister.h" +#include "PhoneNumber.h" + +using namespace Utilities; + +///////////////////////////////////////////////////////////////////////////////////////// +// Token generation + +static char WaKey[] = "/UIGKU1FVQa+ATM2A0za7G2KI9S/CwPYjgAbc67v7ep42eO/WeTLx1lb1cHwxpsEgF4+PmYpLd2YpGUdX/A2JQitsHzDwgcdBpUf7psX1BU="; +static char WaSignature[] = "MIIDMjCCAvCgAwIBAgIETCU2pDALBgcqhkjOOAQDBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMRYwFAYDVQQKEw1XaGF0c0FwcCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEUMBIGA1UEAxMLQnJpYW4gQWN0b24wHhcNMTAwNjI1MjMwNzE2WhcNNDQwMjE1MjMwNzE2WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExFjAUBgNVBAoTDVdoYXRzQXBwIEluYy4xFDASBgNVBAsTC0VuZ2luZWVyaW5nMRQwEgYDVQQDEwtCcmlhbiBBY3RvbjCCAbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDRGYtLgWh7zyRtQainJfCpiaUbzjJuhMgo4fVWZIvXHaSHBU1t5w//S0lDK2hiqkj8KpMWGywVov9eZxZy37V26dEqr/c2m5qZ0E+ynSu7sqUD7kGx/zeIcGT0H+KAVgkGNQCo5Uc0koLRWYHNtYoIvt5R3X6YZylbPftF/8ayWTALBgcqhkjOOAQDBQADLwAwLAIUAKYCp0d6z4QQdyN74JDfQ2WCyi8CFDUM4CaNB+ceVXdKtOrNTQcc0e+t"; +static char WaClassesMd5[] = "iV15qOB/jPIidogqfJ/oJA=="; + +std::string WAToken::GenerateToken(const string &number) +{ + unsigned int keyLen, dataLen, classesLen; + mir_ptr key((BYTE*)mir_base64_decode(WaKey, &keyLen)); + mir_ptr data((BYTE*)mir_base64_decode(WaSignature, &dataLen)); + mir_ptr classes((BYTE*)mir_base64_decode(WaClassesMd5, &classesLen)); + + BYTE opad[64], ipad[64]; + memset(opad, 0x5C, sizeof(opad)); + memset(ipad, 0x36, sizeof(ipad)); + for (int i = 0; i < sizeof(opad); i++) { + opad[i] = (BYTE)(opad[i] ^ key[i]); + ipad[i] = (BYTE)(ipad[i] ^ key[i]); + } + + BYTE hash1[MIR_SHA1_HASH_SIZE], hash2[MIR_SHA1_HASH_SIZE]; + mir_sha1_ctx ctx; + mir_sha1_init(&ctx); + mir_sha1_append(&ctx, ipad, sizeof(ipad)); + mir_sha1_append(&ctx, data, dataLen); + mir_sha1_append(&ctx, classes, classesLen); + mir_sha1_append(&ctx, (PBYTE)number.c_str(), (int)number.size()); + mir_sha1_finish(&ctx, hash1); + + mir_sha1_init(&ctx); + mir_sha1_append(&ctx, opad, sizeof(opad)); + mir_sha1_append(&ctx, hash1, sizeof(hash1)); + mir_sha1_finish(&ctx, hash2); + + ptrA result(mir_urlEncode(ptrA(mir_base64_encode(hash2, sizeof(hash2))))); + return std::string(result); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Account registration + +CMStringA WARegister::RequestCodeUrl(const std::string &phoneNumber, const std::string &code) +{ + try { + std::string id = GenerateIdentity(phoneNumber); + + PhoneNumber pn(phoneNumber); + std::string token = WAToken::GenerateToken(pn.Number); + + const char *n = pn.Number.c_str(); + + if (!code.empty()) + return CMStringA(FORMAT, "https://v.whatsapp.net/v2/register?cc=%d&in=%s&id=%s&code=%s", pn.countryCode, n, id.c_str(), code.c_str()); + + return CMStringA(FORMAT, "https://v.whatsapp.net/v2/code?cc=%d&in=%s&to=%d%s&method=sms&mcc=%03d&mnc=%03d&token=%s&id=%s&lg=%s&lc=%s", + pn.countryCode, n, pn.countryCode, n, pn.mcc, pn.mnc, token.c_str(), id.c_str(), pn.ISO639, pn.ISO3166); + } + catch (...) + {} + + return CMStringA(); +} + +std::string WARegister::GenerateIdentity(const std::string &phone) +{ + std::string id = phone; + std::reverse(id.begin(), id.end()); + + BYTE hash[MIR_SHA1_HASH_SIZE]; + mir_sha1_hash((PBYTE)id.c_str(), (int)id.length(), hash); + + id.clear(); + for (int i = 0; i < sizeof(hash); i++) { + char buf[10]; + sprintf_s(buf, "%%%02x", hash[i]); + id += buf; + } + + return id; +} diff --git a/protocols/WhatsApp/src/WhatsAPI++/WARegister.h b/protocols/WhatsApp/src/WhatsAPI++/WARegister.h new file mode 100644 index 0000000000..f2fe0e230b --- /dev/null +++ b/protocols/WhatsApp/src/WhatsAPI++/WARegister.h @@ -0,0 +1,23 @@ +/* + * WARegister.h + */ + +#ifndef WAREGISTER_H_ +#define WAREGISTER_H_ + +#include + +struct WAToken +{ + static std::string GenerateToken(const std::string &number); +}; + +class WARegister +{ + static std::string GenerateIdentity(const std::string &phone); + +public: + static CMStringA RequestCodeUrl(const std::string &phone, const std::string &code); +}; + +#endif /* WAREGISTER_H_ */ diff --git a/protocols/WhatsApp/src/WhatsAPI++/utilities.cpp b/protocols/WhatsApp/src/WhatsAPI++/utilities.cpp index f2603f9f8d..dc28b86c69 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/utilities.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/utilities.cpp @@ -13,41 +13,24 @@ #include #include -namespace Utilities{ - +namespace Utilities { + const static char digits[] = { - '0' , '1' , '2' , '3' , '4' , '5' , - '6' , '7' , '8' , '9' , 'a' , 'b' , - 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , - 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , - 'o' , 'p' , 'q' , 'r' , 's' , 't' , - 'u' , 'v' , 'w' , 'x' , 'y' , 'z' + '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z' }; -void configureLogging(const char* ident) { -#ifndef _LOGWIN32 - openlog(ident, 0, LOG_USER); -#endif -} - -void closeLog() { -#ifndef _LOGWIN32 - closelog(); -#endif -} - -std::string getCountryCode(){ - return "34"; -} - std::string reverseString(const std::string& str) { return std::string(str.rbegin(), str.rend()); } - - -std::string itoa(int value, unsigned int base) { +std::string itoa(int value, unsigned int base) +{ const char digitMap[] = "0123456789abcdef"; @@ -70,8 +53,8 @@ std::string itoa(int value, unsigned int base) { // Translating number to string with base: - for (int i = 30; _value && i ; --i) { - buf = digitMap[ _value % base ] + buf; + for (int i = 30; _value && i; --i) { + buf = digitMap[_value % base] + buf; _value /= base; } @@ -79,24 +62,26 @@ std::string itoa(int value, unsigned int base) { } -std::string processIdentity(const std::string& id){ +std::string processIdentity(const std::string& id) +{ std::string buffer_str = reverseString(id); - unsigned char digest[16]; - md5_string(buffer_str, digest); + unsigned char digest[16]; + md5_string(buffer_str, digest); buffer_str.clear(); - for(int i =0; i < 16; i++){ - int tmp = digest[i]+128; + for (int i = 0; i < 16; i++) { + int tmp = digest[i] + 128; int f = tmp & 0xff; - buffer_str = buffer_str.append(itoa(f,16)); + buffer_str = buffer_str.append(itoa(f, 16)); } return buffer_str; } -void debug(const std::string& msg) { +void debug(const std::string& msg) +{ #ifdef _LOGWIN32 cout << "DEBUG: " << msg << endl; #else @@ -104,7 +89,8 @@ void debug(const std::string& msg) { #endif } -std::string str(int64_t i, int radix ) { +std::string str(int64_t i, int radix) +{ if (radix < 2 || radix > 36) throw WAException("radix must be in 2..36"); char buf[65]; @@ -130,34 +116,39 @@ std::string str(int64_t i, int radix ) { return std::string(aux, charPos, (65 - charPos)); } -int64_t randLong() { +int64_t randLong() +{ std::srand((unsigned)time(NULL)); - int64_t r = (int64_t) ((char) (std::rand() % 256)); + int64_t r = (int64_t)((char)(std::rand() % 256)); - for (int i = 0; i < 7 ; i++) - r = (r << 8) + ((char) (std::rand() % 256)); + for (int i = 0; i < 7; i++) + r = (r << 8) + ((char)(std::rand() % 256)); return r; } -int64_t absLong(int64_t num) { - return (num >= 0? num: -num); +int64_t absLong(int64_t num) +{ + return (num >= 0 ? num : -num); } -std::string intToStr(int i) { +std::string intToStr(int i) +{ std::stringstream convert; convert << i; return convert.str(); } -std::string doubleToStr(double d) { +std::string doubleToStr(double d) +{ std::stringstream convert; convert << d; return convert.str(); } -time_t parseBBDate(const string& s) { +time_t parseBBDate(const string& s) +{ _LOGDATA("parse DATE %s", s.c_str()); if (s.length() < 17) return time(NULL); @@ -165,16 +156,17 @@ time_t parseBBDate(const string& s) { struct tm timeinfo; timeinfo.tm_year = atoi(s.substr(0, 4).c_str()) - 1900; timeinfo.tm_mon = atoi(s.substr(4, 2).c_str()) - 1; - timeinfo.tm_mday = atoi(s.substr(6,2).c_str()); - timeinfo.tm_hour = atoi(s.substr(9,2).c_str()); - timeinfo.tm_min = atoi(s.substr(12,2).c_str()); - timeinfo.tm_sec = atoi(s.substr(15,2).c_str()); + timeinfo.tm_mday = atoi(s.substr(6, 2).c_str()); + timeinfo.tm_hour = atoi(s.substr(9, 2).c_str()); + timeinfo.tm_min = atoi(s.substr(12, 2).c_str()); + timeinfo.tm_sec = atoi(s.substr(15, 2).c_str()); //return timegm(&timeinfo); - return mktime(&timeinfo); + return mktime(&timeinfo); } -void logData(const char *format, ...) { +void logData(const char *format, ...) +{ va_list args; va_start(args, format); #ifdef _LOGWIN32 @@ -186,7 +178,8 @@ void logData(const char *format, ...) { } -long long parseLongLong(const std::string& str) { +long long parseLongLong(const std::string& str) +{ std::stringstream sstr(str); long long val; sstr >> val; @@ -194,8 +187,9 @@ long long parseLongLong(const std::string& str) { return val; } -string bytesToHex(unsigned char* bytes, int length) { - string ret(length*2, ' '); +string bytesToHex(unsigned char* bytes, int length) +{ + string ret(length * 2, ' '); string::iterator p = ret.begin(); int i = 0; for (int c = 0; c < length; c++) { @@ -207,13 +201,15 @@ string bytesToHex(unsigned char* bytes, int length) { return ret; } -unsigned char forDigit(int b) { +unsigned char forDigit(int b) +{ if (b < 10) - return (unsigned char) (48 + b); - return (unsigned char) (97 + b - 10); + return (unsigned char)(48 + b); + return (unsigned char)(97 + b - 10); } -bool saveStringToFile(const string& data, const string& filePath) { +bool saveStringToFile(const string& data, const string& filePath) +{ std::ofstream out(filePath.c_str()); if (out.fail()) return false; out << data; @@ -223,10 +219,11 @@ bool saveStringToFile(const string& data, const string& filePath) { return true; } -bool saveBytesToFile(const std::vector& data, const string& filePath) { +bool saveBytesToFile(const std::vector& data, const string& filePath) +{ std::fstream out(filePath.c_str(), ios::out | ios::binary); if (out.fail()) return false; - out.write((const char*) &data[0], data.size()); + out.write((const char*)&data[0], data.size()); if (out.fail()) return false; out.close(); if (out.fail()) return false; @@ -234,7 +231,8 @@ bool saveBytesToFile(const std::vector& data, const string& fileP } -bool saveBytesToFile(const string& data, const string& filePath) { +bool saveBytesToFile(const string& data, const string& filePath) +{ std::fstream out(filePath.c_str(), ios::out | ios::binary); if (out.fail()) return false; out.write(data.c_str(), data.length()); @@ -244,7 +242,8 @@ bool saveBytesToFile(const string& data, const string& filePath) { return true; } -vector* loadFileToBytes(const string& path) { +vector* loadFileToBytes(const string& path) +{ vector* bytes = NULL; std::ifstream in(path.c_str(), ios::in | ios::binary | ios::ate); size_t size = in.tellg(); @@ -254,19 +253,21 @@ vector* loadFileToBytes(const string& path) { char *buffer = new char[size]; in.read(buffer, size); bytes = new vector(buffer, buffer + size); - delete [] buffer; + delete[] buffer; in.close(); if (in.fail()) return NULL; return bytes; } -bool fileExists(const std::string& path) { +bool fileExists(const std::string& path) +{ return _access(path.c_str(), 0) == 0; } -string removeWaDomainFromJid(const string& jid) { +string removeWaDomainFromJid(const string& jid) +{ string result = jid; size_t index = jid.find("@s.whatsapp.net"); @@ -284,7 +285,8 @@ string removeWaDomainFromJid(const string& jid) { return jid; } -string getNameFromPath(const std::string& path) { +string getNameFromPath(const std::string& path) +{ size_t i = path.rfind('/'); if (i == string::npos) i = 0; @@ -293,11 +295,13 @@ string getNameFromPath(const std::string& path) { return path.substr(i); } -vector* getChallengeData(const std::string& challengeFile) { +vector* getChallengeData(const std::string& challengeFile) +{ return loadFileToBytes(challengeFile); } -bool saveChallengeData(const std::vector& data, const std::string& challengeFile) { +bool saveChallengeData(const std::vector& data, const std::string& challengeFile) +{ return saveBytesToFile(data, challengeFile); } @@ -305,42 +309,34 @@ std::string utf8_to_utf16(const std::string& utf8) { std::vector unicode; size_t i = 0; - while (i < utf8.size()) - { + while (i < utf8.size()) { unsigned long uni; size_t todo; bool error = false; unsigned char ch = utf8[i++]; - if (ch <= 0x7F) - { + if (ch <= 0x7F) { uni = ch; todo = 0; } - else if (ch <= 0xBF) - { + else if (ch <= 0xBF) { throw std::logic_error("not a UTF-8 string"); } - else if (ch <= 0xDF) - { - uni = ch&0x1F; + else if (ch <= 0xDF) { + uni = ch & 0x1F; todo = 1; } - else if (ch <= 0xEF) - { - uni = ch&0x0F; + else if (ch <= 0xEF) { + uni = ch & 0x0F; todo = 2; } - else if (ch <= 0xF7) - { - uni = ch&0x07; + else if (ch <= 0xF7) { + uni = ch & 0x07; todo = 3; } - else - { + else { throw std::logic_error("not a UTF-8 string"); } - for (size_t j = 0; j < todo; ++j) - { + for (size_t j = 0; j < todo; ++j) { if (i == utf8.size()) throw std::logic_error("not a UTF-8 string"); unsigned char ch = utf8[i++]; @@ -356,86 +352,63 @@ std::string utf8_to_utf16(const std::string& utf8) unicode.push_back(uni); } std::string utf16; - for (size_t i = 0; i < unicode.size(); ++i) - { + for (size_t i = 0; i < unicode.size(); ++i) { unsigned long uni = unicode[i]; if (uni <= 0x7F) { - utf16 += (char) uni; + utf16 += (char)uni; } else - if (uni <= 0xFFFF) - { + if (uni <= 0xFFFF) { stringstream value; value << std::setw(4) << std::setfill('0') << Utilities::itoa(uni, 16).c_str(); utf16 += "\\u" + value.str(); - } - else - { - stringstream value1, value2; - uni -= 0x10000; - value1 << std::setw(4) << std::setfill('0') << Utilities::itoa(((uni >> 10) + 0xD800), 16); - utf16 += "\\u" + value1.str(); - - value2 << std::setw(4) << std::setfill('0') << Utilities::itoa(((uni & 0x3FF) + 0xDC00), 16); - utf16 += "\\u" + value2.str(); - } + } + else { + stringstream value1, value2; + uni -= 0x10000; + value1 << std::setw(4) << std::setfill('0') << Utilities::itoa(((uni >> 10) + 0xD800), 16); + utf16 += "\\u" + value1.str(); + + value2 << std::setw(4) << std::setfill('0') << Utilities::itoa(((uni & 0x3FF) + 0xDC00), 16); + utf16 += "\\u" + value2.str(); + } } return utf16; } std::string string_format(const char* fmt, va_list ap) { - int size = 100; - std::string str; - while (1) { - str.resize(size); - //va_start(ap, fmt); - int n = vsnprintf((char *)str.c_str(), size, fmt, ap); - //va_end(ap); - if (n > -1 && n < size) { - str.resize(n); - return str; - } - if (n > -1) - size = n + 1; - else - size *= 2; - } - return str; + int size = 100; + std::string str; + while (1) { + str.resize(size); + //va_start(ap, fmt); + int n = vsnprintf((char *)str.c_str(), size, fmt, ap); + //va_end(ap); + if (n > -1 && n < size) { + str.resize(n); + return str; + } + if (n > -1) + size = n + 1; + else + size *= 2; + } + return str; } std::string string_format(const std::string fmt, va_list ap) { - return string_format(fmt.c_str(), ap); - /* - int size = 100; - std::string str; - //va_list ap; - while (1) { - str.resize(size); - //va_start(ap, fmt); - int n = vsnprintf((char *)str.c_str(), size, fmt.c_str(), ap); - //va_end(ap); - if (n > -1 && n < size) { - str.resize(n); - return str; - } - if (n > -1) - size = n + 1; - else - size *= 2; - } - return str; - */ + return string_format(fmt.c_str(), ap); } std::string string_format(const std::string fmt, ...) { - va_list ap; - va_start(ap, fmt); - std::string ret = string_format(fmt, ap); - va_end(ap); - return ret; + va_list ap; + va_start(ap, fmt); + std::string ret = string_format(fmt, ap); + va_end(ap); + return ret; } } diff --git a/protocols/WhatsApp/src/WhatsAPI++/utilities.h b/protocols/WhatsApp/src/WhatsAPI++/utilities.h index fec1b29862..d0096489e2 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/utilities.h +++ b/protocols/WhatsApp/src/WhatsAPI++/utilities.h @@ -49,9 +49,6 @@ std::string base64_encode(void*, size_t); void md5_string(const std::string& data, unsigned char digest[16]); namespace Utilities{ - void configureLogging(const char* ident); - void closeLog(); - string getCountryCode(); string getMcc(); string getMnc(); string reverseString(const string& str); @@ -78,9 +75,5 @@ namespace Utilities{ std::vector* getChallengeData(const std::string& file); bool saveChallengeData(const std::vector& data, const std::string& file); std::string utf8_to_utf16(const std::string& utf8); - std::string string_format(const std::string fmt, ...); - std::string string_format(const std::string fmt, va_list ap); - std::string string_format(const char* fmt, va_list ap); } #endif - diff --git a/protocols/WhatsApp/src/chat.cpp b/protocols/WhatsApp/src/chat.cpp index bef230ecfd..d06e8f357e 100644 --- a/protocols/WhatsApp/src/chat.cpp +++ b/protocols/WhatsApp/src/chat.cpp @@ -2,12 +2,12 @@ // #TODO Remove, as we are not using the chat-module for groups anymore -INT_PTR WhatsAppProto::OnJoinChat(WPARAM,LPARAM) +INT_PTR WhatsAppProto::OnJoinChat(WPARAM, LPARAM) { return 0; } -INT_PTR WhatsAppProto::OnLeaveChat(WPARAM,LPARAM) +INT_PTR WhatsAppProto::OnLeaveChat(WPARAM, LPARAM) { return 0; } @@ -18,55 +18,50 @@ int WhatsAppProto::OnChatOutgoing(WPARAM wParam, LPARAM lParam) char *text; char *id; - if (strcmp(hook->pDest->pszModule,m_szModuleName)) + if (strcmp(hook->pDest->pszModule, m_szModuleName)) return 0; - switch(hook->pDest->iType) - { + switch (hook->pDest->iType) { case GC_USER_MESSAGE: - { - text = mir_t2a_cp(hook->ptszText,CP_UTF8); - std::string msg = text; + text = mir_t2a_cp(hook->ptszText, CP_UTF8); + { + std::string msg = text; - id = mir_t2a_cp(hook->pDest->ptszID,CP_UTF8); - std::string chat_id = id; + id = mir_t2a_cp(hook->pDest->ptszID, CP_UTF8); + std::string chat_id = id; - mir_free(text); - mir_free(id); - - if (isOnline()) { - MCONTACT hContact = this->ContactIDToHContact(chat_id); - if (hContact) - { - debugLogA("**Chat - Outgoing message: %s", text); - this->SendMsg(hContact, IS_CHAT, msg.c_str()); - - // #TODO Move to SendMsgWorker, otherwise all messages are "acknowledged" by Miranda + mir_free(text); + mir_free(id); - GCDEST gcd = { m_szModuleName, hook->pDest->ptszID, GC_EVENT_MESSAGE }; - GCEVENT gce = { sizeof(gce), &gcd }; - gce.dwFlags = GCEF_ADDTOLOG; - gce.ptszNick = mir_a2t(this->nick.c_str()); - gce.ptszUID = mir_a2t(this->jid.c_str()); - gce.time = time(NULL); - gce.ptszText = hook->ptszText; - gce.bIsMe = TRUE; - CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); + if (isOnline()) { + MCONTACT hContact = this->ContactIDToHContact(chat_id); + if (hContact) { + debugLogA("**Chat - Outgoing message: %s", text); + this->SendMsg(hContact, IS_CHAT, msg.c_str()); - mir_free((void*)gce.ptszUID); - mir_free((void*)gce.ptszNick); + // #TODO Move to SendMsgWorker, otherwise all messages are "acknowledged" by Miranda + + GCDEST gcd = { m_szModuleName, hook->pDest->ptszID, GC_EVENT_MESSAGE }; + GCEVENT gce = { sizeof(gce), &gcd }; + gce.dwFlags = GCEF_ADDTOLOG; + gce.ptszNick = mir_a2t(this->nick.c_str()); + gce.ptszUID = mir_a2t(this->jid.c_str()); + gce.time = time(NULL); + gce.ptszText = hook->ptszText; + gce.bIsMe = TRUE; + CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); + + mir_free((void*)gce.ptszUID); + mir_free((void*)gce.ptszNick); + } } } - break; - } case GC_USER_LEAVE: case GC_SESSION_TERMINATE: - { break; } - } return 0; } diff --git a/protocols/WhatsApp/src/common.h b/protocols/WhatsApp/src/common.h index 8c998ecb61..ea2af49172 100644 --- a/protocols/WhatsApp/src/common.h +++ b/protocols/WhatsApp/src/common.h @@ -58,6 +58,7 @@ Copyright #include #include #include +#include #include #include #include diff --git a/protocols/WhatsApp/src/connection.cpp b/protocols/WhatsApp/src/connection.cpp index 5fc08ec1dc..a76ad89522 100644 --- a/protocols/WhatsApp/src/connection.cpp +++ b/protocols/WhatsApp/src/connection.cpp @@ -2,35 +2,28 @@ void WhatsAppProto::ChangeStatus(void*) { - if (m_iDesiredStatus != ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE) - { + if (m_iDesiredStatus != ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE) { ResetEvent(update_loop_lock_); ForkThread(&WhatsAppProto::sentinelLoop, this); ForkThread(&WhatsAppProto::stayConnectedLoop, this); } - else if (m_iStatus == ID_STATUS_INVISIBLE && m_iDesiredStatus == ID_STATUS_ONLINE) - { - if (this->connection != NULL) - { + else if (m_iStatus == ID_STATUS_INVISIBLE && m_iDesiredStatus == ID_STATUS_ONLINE) { + if (this->connection != NULL) { this->connection->sendAvailableForChat(); m_iStatus = ID_STATUS_ONLINE; - ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, ID_STATUS_INVISIBLE); + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_INVISIBLE); } } - else if (m_iStatus == ID_STATUS_ONLINE && m_iDesiredStatus == ID_STATUS_INVISIBLE) - { - if (this->connection != NULL) - { + else if (m_iStatus == ID_STATUS_ONLINE && m_iDesiredStatus == ID_STATUS_INVISIBLE) { + if (this->connection != NULL) { this->connection->sendClose(); m_iStatus = ID_STATUS_INVISIBLE; - SetAllContactStatuses( ID_STATUS_OFFLINE, true ); - ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, ID_STATUS_ONLINE); + SetAllContactStatuses(ID_STATUS_OFFLINE, true); + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_ONLINE); } } - else if (m_iDesiredStatus == ID_STATUS_OFFLINE) - { - if (this->conn != NULL) - { + else if (m_iDesiredStatus == ID_STATUS_OFFLINE) { + if (this->conn != NULL) { SetEvent(update_loop_lock_); this->conn->forceShutdown(); debugLogA("Forced shutdown"); @@ -42,58 +35,50 @@ void WhatsAppProto::stayConnectedLoop(void*) { bool error = true; std::string cc, in, pass; - DBVARIANT dbv = {0}; + DBVARIANT dbv = { 0 }; - if ( !getString(WHATSAPP_KEY_CC, &dbv)) - { + if (!getString(WHATSAPP_KEY_CC, &dbv)) { cc = dbv.pszVal; db_free(&dbv); error = cc.empty(); } - if (error) - { - NotifyEvent(m_tszUserName,TranslateT("Please enter a country-code."),NULL,WHATSAPP_EVENT_CLIENT); + if (error) { + NotifyEvent(m_tszUserName, TranslateT("Please enter a country-code."), NULL, WHATSAPP_EVENT_CLIENT); return; } error = true; - if ( !getString(WHATSAPP_KEY_LOGIN, &dbv)) - { + if (!getString(WHATSAPP_KEY_LOGIN, &dbv)) { in = dbv.pszVal; db_free(&dbv); error = in.empty(); } - if (error) - { - NotifyEvent(m_tszUserName,TranslateT("Please enter a phone-number without country code."),NULL,WHATSAPP_EVENT_CLIENT); + if (error) { + NotifyEvent(m_tszUserName, TranslateT("Please enter a phone-number without country code."), NULL, WHATSAPP_EVENT_CLIENT); return; } this->phoneNumber = cc + in; this->jid = this->phoneNumber + "@s.whatsapp.net"; error = true; - if ( !getString(WHATSAPP_KEY_NICK, &dbv)) - { + if (!getString(WHATSAPP_KEY_NICK, &dbv)) { this->nick = dbv.pszVal; db_free(&dbv); error = nick.empty(); } - if (error) - { + if (error) { NotifyEvent(m_tszUserName, TranslateT("Please enter a nickname."), NULL, WHATSAPP_EVENT_CLIENT); return; } error = true; - if ( !getString(WHATSAPP_KEY_PASS, &dbv)) - { + if (!getString(WHATSAPP_KEY_PASS, &dbv)) { pass = dbv.pszVal; db_free(&dbv); error = pass.empty(); } - if (error) - { - NotifyEvent(m_tszUserName,TranslateT("Please enter a password."),NULL,WHATSAPP_EVENT_CLIENT); + if (error) { + NotifyEvent(m_tszUserName, TranslateT("Please enter a password."), NULL, WHATSAPP_EVENT_CLIENT); return; } @@ -105,41 +90,36 @@ void WhatsAppProto::stayConnectedLoop(void*) this->conn = NULL; - while (true) - { - if (connection != NULL) - { - if (connection->getLogin() == NULL && login != NULL) - { + while (true) { + if (connection != NULL) { + if (connection->getLogin() == NULL && login != NULL) { delete login; login = NULL; } delete connection; connection = NULL; } - if (this->conn != NULL) - { + if (this->conn != NULL) { delete this->conn; this->conn = NULL; } desiredStatus = this->m_iDesiredStatus; - if (desiredStatus == ID_STATUS_OFFLINE || error) - { + if (desiredStatus == ID_STATUS_OFFLINE || error) { debugLogA("Set status to offline"); - SetAllContactStatuses( ID_STATUS_OFFLINE, true ); + SetAllContactStatuses(ID_STATUS_OFFLINE, true); this->ToggleStatusMenuItems(false); int prevStatus = this->m_iStatus; this->m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, prevStatus); + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, prevStatus); break; } debugLogA("Connecting..."); this->m_iStatus = ID_STATUS_CONNECTING; - ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_OFFLINE, m_iStatus); + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_OFFLINE, m_iStatus); - CODE_BLOCK_TRY + try { unsigned passLen; ptrA passBin((char*)mir_base64_decode(pass.c_str(), &passLen)); std::string password(passBin, passLen), resource = ACCOUNT_RESOURCE; @@ -148,13 +128,13 @@ void WhatsAppProto::stayConnectedLoop(void*) portNumber = 443, resource += "-443"; else portNumber = 5222, resource += "-5222"; - + this->conn = new WASocketConnection("c.whatsapp.net", portNumber); connection = new WAConnection(&this->connMutex, this, this); login = new WALogin(connection, new BinTreeNodeReader(connection, conn, WAConnection::dictionary, WAConnection::DICTIONARY_LEN), - new BinTreeNodeWriter(connection, conn, WAConnection::dictionary, WAConnection::DICTIONARY_LEN, &writerMutex), - "s.whatsapp.net", this->phoneNumber, resource, password, nick); + new BinTreeNodeWriter(connection, conn, WAConnection::dictionary, WAConnection::DICTIONARY_LEN, &writerMutex), + "s.whatsapp.net", this->phoneNumber, resource, password, nick); std::vector* nextChallenge = login->login(*this->challenge); delete this->challenge; @@ -167,27 +147,31 @@ void WhatsAppProto::stayConnectedLoop(void*) debugLogA("Set status to online"); this->m_iStatus = desiredStatus; - ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE )m_iStatus, ID_STATUS_CONNECTING); + ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_CONNECTING); this->ToggleStatusMenuItems(true); ForkThread(&WhatsAppProto::ProcessBuddyList, this); // #TODO Move out of try block. Exception is expected on disconnect bool cont = true; - while (cont == true) - { + while (cont == true) { this->lastPongTime = time(NULL); cont = connection->read(); } debugLogA("Exit from read-loop"); - - CODE_BLOCK_CATCH(WAException) + } + catch (WAException &e) { + debugLogA("Exception: %s", e.what()); error = true; - CODE_BLOCK_CATCH(exception) + } + catch (exception &e) { + debugLogA("Exception: %s", e.what()); error = true; - CODE_BLOCK_CATCH_UNKNOWN + } + catch (...) { + debugLogA("Unknown exception"); error = true; - CODE_BLOCK_END + } } debugLogA("Break out from loop"); } @@ -196,30 +180,23 @@ void WhatsAppProto::sentinelLoop(void*) { int delay = MAX_SILENT_INTERVAL; int quietInterval; - while (WaitForSingleObjectEx(update_loop_lock_, delay * 1000, true) == WAIT_TIMEOUT) - { - if (this->m_iStatus != ID_STATUS_OFFLINE && this->connection != NULL && this->m_iDesiredStatus == this->m_iStatus) - { + while (WaitForSingleObjectEx(update_loop_lock_, delay * 1000, true) == WAIT_TIMEOUT) { + if (this->m_iStatus != ID_STATUS_OFFLINE && this->connection != NULL && this->m_iDesiredStatus == this->m_iStatus) { // #TODO Quiet after pong or tree read? quietInterval = difftime(time(NULL), this->lastPongTime); - if (quietInterval >= MAX_SILENT_INTERVAL) - { - CODE_BLOCK_TRY + if (quietInterval >= MAX_SILENT_INTERVAL) { + try { debugLogA("send ping"); this->lastPongTime = time(NULL); this->connection->sendPing(); - CODE_BLOCK_CATCH(exception) - CODE_BLOCK_END - } - else - { - delay = MAX_SILENT_INTERVAL - quietInterval; + } + catch (exception &e) { + debugLogA("Exception: %s", e.what()); + } } + else delay = MAX_SILENT_INTERVAL - quietInterval; } - else - { - delay = MAX_SILENT_INTERVAL; - } + else delay = MAX_SILENT_INTERVAL; } ResetEvent(update_loop_lock_); debugLogA("Exiting sentinel loop"); @@ -228,9 +205,10 @@ void WhatsAppProto::sentinelLoop(void*) void WhatsAppProto::onPing(const std::string& id) { if (this->isOnline()) { - CODE_BLOCK_TRY + try { debugLogA("Sending pong with id %s", id.c_str()); this->connection->sendPong(id); + } CODE_BLOCK_CATCH_ALL } } diff --git a/protocols/WhatsApp/src/constants.h b/protocols/WhatsApp/src/constants.h index 7ec8e6390a..79c54517a6 100644 --- a/protocols/WhatsApp/src/constants.h +++ b/protocols/WhatsApp/src/constants.h @@ -33,7 +33,7 @@ // WhatsApp #define WHATSAPP_LOGIN_SERVER "c.whatsapp.net" -#define ACCOUNT_USER_AGENT "WhatsApp/2.8.3 iPhone_OS/5.0.1 Device/Unknown_(iPhone4,1)" +#define ACCOUNT_USER_AGENT "WhatsApp/2.11.339 Android/4.0.4 Device/GalaxyS3" #define ACCOUNT_URL_CODEREQUEST "https://r.whatsapp.net/v1/code.php" #define ACCOUNT_URL_CODEREQUESTV2 "https://v.whatsapp.net/v2/code" #define ACCOUNT_URL_REGISTERREQUEST "https://r.whatsapp.net/v1/register.php" @@ -43,14 +43,6 @@ // WhatsApp Nokia 302 S40 #define ACCOUNT_RESOURCE "S40-2.3.53" -/* -#define ACCOUNT_USER_AGENT_REGISTRATION "WhatsApp/2.3.53 S40Version/14.26 Device/Nokia302" -#define ACCOUNT_TOKEN_PREFIX1 "PdA2DJyKoUrwLw1Bg6EIhzh502dF9noR9uFCllGk" -#define ACCOUNT_TOKEN_PREFIX2 "1354754753509" -*/ -#define ACCOUNT_USER_AGENT_REGISTRATION "WhatsApp/2.9.4 WP7/7.10.8858 Device/HTC-HTC-H0002" -#define ACCOUNT_TOKEN_PREFIX1 "Od52pFozHNWF9XbTN5lrqDtnsiZGL2G3l9yw1GiQ" -#define ACCOUNT_TOKEN_PREFIX2 "21a31a2d9dbdc9a8ce324ef2df918064fd26e30a" #define WHATSAPP_RECV_MESSAGE 1 #define WHATSAPP_SEND_MESSAGE 2 diff --git a/protocols/WhatsApp/src/contacts.cpp b/protocols/WhatsApp/src/contacts.cpp index 59c32ed746..7bacb6c4a2 100644 --- a/protocols/WhatsApp/src/contacts.cpp +++ b/protocols/WhatsApp/src/contacts.cpp @@ -3,14 +3,13 @@ bool WhatsAppProto::IsMyContact(MCONTACT hContact, bool include_chat) { const char *proto = GetContactProto(hContact); - if( proto && strcmp(m_szModuleName,proto) == 0 ) - { - if( include_chat ) + if (proto && strcmp(m_szModuleName, proto) == 0) { + if (include_chat) return true; - + return !isChatRoom(hContact); } - + return false; } @@ -23,31 +22,24 @@ MCONTACT WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool // First, check if this contact exists hContact = ContactIDToHContact(jid); - if( hContact ) - { - if (new_name != NULL) - { + if (hContact) { + if (new_name != NULL) { DBVARIANT dbv; string oldName; if (db_get_utf(hContact, m_szModuleName, WHATSAPP_KEY_PUSH_NAME, &dbv)) - { oldName = jid.c_str(); - } - else - { + else { oldName = dbv.pszVal; db_free(&dbv); } db_set_utf(hContact, m_szModuleName, WHATSAPP_KEY_PUSH_NAME, new_name); - if (oldName.compare(string(new_name)) != 0) - { - this->NotifyEvent(oldName.c_str(), this->TranslateStr("is now known as '%s'", new_name), - hContact, WHATSAPP_EVENT_OTHER); + if (oldName.compare(string(new_name)) != 0) { + CMString tmp(FORMAT, TranslateT("is now known as '%s'"), new_name); + this->NotifyEvent(_A2T(oldName.c_str()), tmp, hContact, WHATSAPP_EVENT_OTHER); } } - if (db_get_b(hContact, "CList", "Hidden", 0) > 0) - { + if (db_get_b(hContact, "CList", "Hidden", 0) > 0) { db_unset(hContact, "CList", "Hidden"); } return hContact; @@ -56,10 +48,8 @@ MCONTACT WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool // If not, make a new contact! hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); - if (hContact) - { - if (CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)m_szModuleName) == 0) - { + if (hContact) { + if (CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)m_szModuleName) == 0) { setString(hContact, "ID", jid.c_str()); debugLogA("Added contact %s", jid.c_str()); setString(hContact, "MirVer", "WhatsApp"); @@ -70,7 +60,7 @@ MCONTACT WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool std::string newNameStr; if (hasNickName) { - newNameStr = new_name; + newNameStr = new_name; } DBEVENTINFO dbei = {0}; @@ -81,7 +71,7 @@ MCONTACT WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool dbei.eventType = EVENTTYPE_ADDED; dbei.cbBlob = sizeof(DWORD) * 2 + newNameStr.length() + 5; - PBYTE pCurBlob = dbei.pBlob = ( PBYTE ) mir_alloc( dbei.cbBlob ); + PBYTE pCurBlob = dbei.pBlob = ( PBYTE ) mir_alloc( dbei.cbBlob ); *(PDWORD)pCurBlob = 0; pCurBlob += sizeof(DWORD); // UID *(PDWORD)pCurBlob = (DWORD)hContact; pCurBlob += sizeof(DWORD); // Contact Handle strcpy((char*)pCurBlob, newNameStr.data()); pCurBlob += newNameStr.length()+1; // Nickname @@ -94,8 +84,7 @@ MCONTACT WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool */ DBVARIANT dbv; - if( !getTString(WHATSAPP_KEY_DEF_GROUP, &dbv)) - { + if (!getTString(WHATSAPP_KEY_DEF_GROUP, &dbv)) { db_set_ws(hContact, "CList", "Group", dbv.ptszVal); db_free(&dbv); } @@ -124,10 +113,7 @@ MCONTACT WhatsAppProto::ContactIDToHContact(const std::string& phoneNumber) const char* idForContact = "ID"; const char* idForChat = "ChatRoomID"; - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - if (!IsMyContact(hContact, true)) - continue; - + for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { const char* id = isChatRoom(hContact) ? idForChat : idForContact; DBVARIANT dbv; @@ -147,8 +133,8 @@ MCONTACT WhatsAppProto::ContactIDToHContact(const std::string& phoneNumber) void WhatsAppProto::SetAllContactStatuses(int status, bool reset_client) { - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - if (!IsMyContact(hContact)) + for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { + if (isChatRoom(hContact)) continue; if (reset_client) { @@ -171,36 +157,37 @@ void WhatsAppProto::ProcessBuddyList(void*) { std::vector jids; DBVARIANT dbv; - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - if (!IsMyContact(hContact)) + for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { + if (isChatRoom(hContact)) continue; if (!getString(hContact, WHATSAPP_KEY_ID, &dbv)) { std::string id(dbv.pszVal); db_free(&dbv); - CODE_BLOCK_TRY - if (!db_get_b(hContact, "CList", "Hidden", 0)) - { + try { + if (!db_get_b(hContact, "CList", "Hidden", 0)) { // Do not request picture for inactive groups - this would make the group visible again jids.push_back(id); } - if (getByte(hContact, "SimpleChatRoom", 0) == 0) - { + if (getByte(hContact, "SimpleChatRoom", 0) == 0) { this->connection->sendQueryLastOnline(id); this->connection->sendPresenceSubscriptionRequest(id); } + } CODE_BLOCK_CATCH_ALL } } if (jids.size() > 0) { - CODE_BLOCK_TRY + try { this->connection->sendGetPictureIds(jids); + } CODE_BLOCK_CATCH_ALL } - CODE_BLOCK_TRY + try { this->connection->sendGetGroups(); this->connection->sendGetOwningGroups(); + } CODE_BLOCK_CATCH_ALL } @@ -220,10 +207,8 @@ void WhatsAppProto::SearchAckThread(void *targ) void WhatsAppProto::onAvailable(const std::string& paramString, bool paramBoolean) { MCONTACT hContact = this->AddToContactList(paramString, 0, false); - if (hContact != NULL) - { - if (paramBoolean) - { + if (hContact != NULL) { + if (paramBoolean) { /* this->connection->sendGetPicture(paramString, "image", "old", "new"); std::vector ids; @@ -232,13 +217,12 @@ void WhatsAppProto::onAvailable(const std::string& paramString, bool paramBoolea */ setWord(hContact, "Status", ID_STATUS_ONLINE); } - else - { + else { setWord(hContact, "Status", ID_STATUS_OFFLINE); this->UpdateStatusMsg(hContact); } } - + setDword(hContact, WHATSAPP_KEY_LAST_SEEN, 0); this->UpdateStatusMsg(hContact); } @@ -249,17 +233,17 @@ void WhatsAppProto::onLastSeen(const std::string& paramString1, int paramInt, st MCONTACT hContact = this->ContactIDToHContact(paramString1); if (hContact == NULL) { - // This contact was searched - PROTOSEARCHRESULT isr = {0}; - isr.cbSize = sizeof(isr); - isr.flags = PSR_TCHAR; - isr.id = mir_a2t_cp(id.c_str(), CP_UTF8); - isr.nick = ""; - isr.firstName = ""; - isr.lastName = ""; - isr.email = ""; - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, targ, (LPARAM)&isr); - // #TODO + // This contact was searched + PROTOSEARCHRESULT isr = {0}; + isr.cbSize = sizeof(isr); + isr.flags = PSR_TCHAR; + isr.id = mir_a2t_cp(id.c_str(), CP_UTF8); + isr.nick = ""; + isr.firstName = ""; + isr.lastName = ""; + isr.email = ""; + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, targ, (LPARAM)&isr); + // #TODO } */ MCONTACT hContact = this->AddToContactList(paramString1, 0, false); @@ -273,11 +257,10 @@ void WhatsAppProto::UpdateStatusMsg(MCONTACT hContact) std::wstringstream ss; int lastSeen = getDword(hContact, WHATSAPP_KEY_LAST_SEEN, -1); - if (lastSeen != -1) - { + if (lastSeen != -1) { time_t timestamp = time(NULL) - lastSeen; TCHAR stzLastSeen[MAX_PATH]; - _tcsftime(stzLastSeen,SIZEOF(stzLastSeen),TranslateT("Last seen on %x at %X"),localtime(×tamp)); + _tcsftime(stzLastSeen, SIZEOF(stzLastSeen), TranslateT("Last seen on %x at %X"), localtime(×tamp)); ss << stzLastSeen; } @@ -292,8 +275,7 @@ void WhatsAppProto::UpdateStatusMsg(MCONTACT hContact) void WhatsAppProto::onPictureChanged(const std::string& from, const std::string& author, bool set) { - if (this->isOnline()) - { + if (this->isOnline()) { vector ids; ids.push_back(from); this->connection->sendGetPictureIds(ids); @@ -303,83 +285,71 @@ void WhatsAppProto::onPictureChanged(const std::string& from, const std::string& void WhatsAppProto::onSendGetPicture(const std::string& jid, const std::vector& data, const std::string& oldId, const std::string& newId) { MCONTACT hContact = this->ContactIDToHContact(jid); - if (hContact) - { + if (hContact) { debugLogA("Updating avatar for jid %s", jid.c_str()); // Save avatar - std::tstring filename = this->GetAvatarFolder() ; + std::tstring filename = this->GetAvatarFolder(); if (_taccess(filename.c_str(), 0)) CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)filename.c_str()); - filename = filename + _T("\\") + (TCHAR*) _A2T(jid.c_str()) + _T("-") + (TCHAR*) _A2T(newId.c_str()) +_T(".jpg"); + filename = filename + _T("\\") + (TCHAR*)_A2T(jid.c_str()) + _T("-") + (TCHAR*)_A2T(newId.c_str()) + _T(".jpg"); FILE *f = _tfopen(filename.c_str(), _T("wb")); int r = (int)fwrite(std::string(data.begin(), data.end()).c_str(), 1, data.size(), f); fclose(f); - PROTO_AVATAR_INFORMATIONT ai = {sizeof(ai)}; + PROTO_AVATAR_INFORMATIONT ai = { sizeof(ai) }; ai.hContact = hContact; ai.format = PA_FORMAT_JPEG; _tcsncpy(ai.filename, filename.c_str(), SIZEOF(ai.filename)); - ai.filename[SIZEOF(ai.filename)-1] = 0; + ai.filename[SIZEOF(ai.filename) - 1] = 0; int ackResult; - if (r > 0) - { + if (r > 0) { setString(hContact, WHATSAPP_KEY_AVATAR_ID, newId.c_str()); ackResult = ACKRESULT_SUCCESS; } - else - { + else { ackResult = ACKRESULT_FAILED; } ProtoBroadcastAck(ai.hContact, ACKTYPE_AVATAR, ackResult, (HANDLE)&ai, 0); } } -void WhatsAppProto::onSendGetPictureIds(std::map* ids) +void WhatsAppProto::onSendGetPictureIds(std::map* ids) { - for (std::map::iterator it = ids->begin(); it != ids->end(); ++it) - { + for (std::map::iterator it = ids->begin(); it != ids->end(); ++it) { MCONTACT hContact = this->AddToContactList(it->first); - if (hContact != NULL) - { + if (hContact != NULL) { DBVARIANT dbv; std::string oldId; if (getString(hContact, WHATSAPP_KEY_AVATAR_ID, &dbv)) oldId = ""; - else - { + else { oldId = dbv.pszVal; db_free(&dbv); } - if (it->second.size() > 0 && it->second.compare(oldId) != 0) - { - CODE_BLOCK_TRY + if (it->second.size() > 0 && it->second.compare(oldId) != 0) { + try { this->connection->sendGetPicture(it->first, "image", oldId, it->second); + } CODE_BLOCK_CATCH_ALL } } } } -string WhatsAppProto::GetContactDisplayName(MCONTACT hContact) -{ - return string((CHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, 0)); -} - -string WhatsAppProto::GetContactDisplayName(const string& jid) +TCHAR* WhatsAppProto::GetContactDisplayName(const string& jid) { MCONTACT hContact = this->ContactIDToHContact(jid); - return hContact ? this->GetContactDisplayName(hContact) : (string("+")+ Utilities::removeWaDomainFromJid(jid)); + return (hContact) ? pcli->pfnGetContactDisplayName(hContact, 0) : _T("none"); } // Group contacts -------------------------- void WhatsAppProto::SendGetGroupInfoWorker(void* data) { - if (this->isOnline()) - { + if (this->isOnline()) { this->connection->sendGetGroupInfo(*((std::string*) data)); } } @@ -388,8 +358,7 @@ void WhatsAppProto::onGroupInfo(const std::string& gjid, const std::string& owne { debugLogA("'%s', '%s', '%s', '%s'", gjid.c_str(), ownerJid.c_str(), subject.c_str(), createrJid.c_str()); MCONTACT hContact = ContactIDToHContact(gjid); - if (!hContact) - { + if (!hContact) { debugLogA("Group info requested for non existing contact '%s'", gjid.c_str()); return; } @@ -401,7 +370,7 @@ void WhatsAppProto::onGroupInfo(const std::string& gjid, const std::string& owne void WhatsAppProto::onGroupInfoFromList(const std::string& paramString1, const std::string& paramString2, const std::string& paramString3, const std::string& paramString4, int paramInt1, int paramInt2) { // Called before onOwningGroups() or onParticipatingGroups() is called! - debugLogA(""); + } void WhatsAppProto::onGroupNewSubject(const std::string& from, const std::string& author, const std::string& newSubject, int paramInt) @@ -414,55 +383,50 @@ void WhatsAppProto::onGroupAddUser(const std::string& paramString1, const std::s { debugLogA("%s - user: %s", paramString1.c_str(), paramString2.c_str()); MCONTACT hContact = this->AddToContactList(paramString1); - std::string groupName(this->GetContactDisplayName(hContact)); + TCHAR *ptszGroupName = pcli->pfnGetContactDisplayName(hContact, 0); - if (paramString2.compare(this->jid) == 0) - { - this->NotifyEvent(groupName, this->TranslateStr("You have been added to the group"), hContact, WHATSAPP_EVENT_OTHER); + if (paramString2.compare(this->jid) == 0) { + this->NotifyEvent(ptszGroupName, TranslateT("You have been added to the group"), hContact, WHATSAPP_EVENT_OTHER); setByte(hContact, "IsGroupMember", 1); } - else - { - this->NotifyEvent(groupName, this->TranslateStr("User '%s' has been added to the group", - this->GetContactDisplayName(paramString2).c_str()), hContact, WHATSAPP_EVENT_OTHER); + else { + CMString tmp(FORMAT, TranslateT("User '%s' has been added to the group"), this->GetContactDisplayName(paramString2)); + this->NotifyEvent(ptszGroupName, tmp, hContact, WHATSAPP_EVENT_OTHER); } - if(this->isOnline()) - { + if (this->isOnline()) { this->connection->sendGetGroupInfo(paramString1); } } -void WhatsAppProto::onGroupRemoveUser(const std::string& paramString1, const std::string& paramString2) +void WhatsAppProto::onGroupRemoveUser(const std::string ¶mString1, const std::string ¶mString2) { debugLogA("%s - user: %s", paramString1.c_str(), paramString2.c_str()); MCONTACT hContact = this->ContactIDToHContact(paramString1); if (!hContact) return; - string groupName(this->GetContactDisplayName(hContact)); + TCHAR *ptszGroupName = pcli->pfnGetContactDisplayName(hContact, 0); - if (paramString2.compare(this->jid) == 0) - { + if (paramString2.compare(this->jid) == 0) { //db_set_b(hContact, "CList", "Hidden", 1); setByte(hContact, "IsGroupMember", 0); - - this->NotifyEvent(groupName, this->TranslateStr("You have been removed from the group"), + + this->NotifyEvent(ptszGroupName, TranslateT("You have been removed from the group"), hContact, WHATSAPP_EVENT_OTHER); } - else if(this->isOnline()) - { - this->NotifyEvent(groupName, this->TranslateStr("User '%s' has been removed from the group", - this->GetContactDisplayName(paramString2).c_str()), hContact, WHATSAPP_EVENT_OTHER); + else if (this->isOnline()) { + CMString tmp(FORMAT, TranslateT("User '%s' has been removed from the group"), this->GetContactDisplayName(paramString2)); + this->NotifyEvent(ptszGroupName, tmp, hContact, WHATSAPP_EVENT_OTHER); + this->connection->sendGetGroupInfo(paramString1); - //this->connection->sendGetParticipants(paramString1); } } -void WhatsAppProto::onLeaveGroup(const std::string& paramString) +void WhatsAppProto::onLeaveGroup(const std::string ¶mString) { // Won't be called for unknown reasons! - debugLogA("%s", this->GetContactDisplayName(paramString).c_str()); + debugLogA("%s", this->GetContactDisplayName(paramString)); MCONTACT hContact = this->ContactIDToHContact(paramString); if (hContact) setByte(hContact, "IsGroupMember", 0); @@ -470,7 +434,7 @@ void WhatsAppProto::onLeaveGroup(const std::string& paramString) void WhatsAppProto::onGetParticipants(const std::string& gjid, const std::vector& participants) { - debugLogA("%s", this->GetContactDisplayName(gjid).c_str()); + debugLogA("%s", this->GetContactDisplayName(gjid)); MCONTACT hUserContact, hContact = this->ContactIDToHContact(gjid); if (!hContact) @@ -485,16 +449,13 @@ void WhatsAppProto::onGetParticipants(const std::string& gjid, const std::vector if (isOwningGroup) this->isMemberByGroupContact[hContact].clear(); - for (std::vector::const_iterator it = participants.begin(); it != participants.end(); ++it) - { + for (std::vector::const_iterator it = participants.begin(); it != participants.end(); ++it) { // Hide, if we are not member of the group // Sometimes the group is shown shortly after hiding it again, due to other threads which stored the contact // in a cache before it has been removed (E.g. picture-id list in processBuddyList) - if (isHidden && this->jid.compare(*it) == 0) - { + if (isHidden && this->jid.compare(*it) == 0) { isHidden = false; - if (!isOwningGroup) - { + if (!isOwningGroup) { // Break, as we don't need to collect group-members break; } @@ -503,17 +464,14 @@ void WhatsAppProto::onGetParticipants(const std::string& gjid, const std::vector // #TODO Slow for big count of participants // #TODO If a group is hidden it has been deleted from the local contact list // => don't allow to add users anymore - if (isOwningGroup) - { + if (isOwningGroup) { hUserContact = this->ContactIDToHContact(*it); - if (hUserContact) - { + if (hUserContact) { this->isMemberByGroupContact[hContact][hUserContact] = true; } } } - if (isHidden) - { + if (isHidden) { //db_set_b(hContact, "CList", "Hidden", 1); // #TODO Check if it's possible to reach this point at all setByte(hContact, "IsGroupMember", 0); @@ -523,17 +481,16 @@ void WhatsAppProto::onGetParticipants(const std::string& gjid, const std::vector // Menu handler INT_PTR __cdecl WhatsAppProto::OnAddContactToGroup(WPARAM wParam, LPARAM, LPARAM lParam) { - string a = GetContactDisplayName((MCONTACT)wParam); - string b = GetContactDisplayName((MCONTACT)lParam); - debugLogA("Request add user %s to group %s", a.c_str(), b.c_str()); + TCHAR *a = pcli->pfnGetContactDisplayName((MCONTACT)wParam, 0); + TCHAR *b = pcli->pfnGetContactDisplayName((MCONTACT)lParam, 0); + debugLogA("Request add user %S to group %S", a, b); if (!this->isOnline()) return NULL; DBVARIANT dbv; - if (getString((MCONTACT)wParam, "ID", &dbv)) - return NULL; + return NULL; std::vector participants; participants.push_back(string(dbv.pszVal)); @@ -551,15 +508,14 @@ INT_PTR __cdecl WhatsAppProto::OnAddContactToGroup(WPARAM wParam, LPARAM, LPARAM // Menu handler INT_PTR __cdecl WhatsAppProto::OnRemoveContactFromGroup(WPARAM wParam, LPARAM, LPARAM lParam) { - string a = GetContactDisplayName((MCONTACT)wParam); - string b = GetContactDisplayName((MCONTACT)lParam); - debugLogA("Request remove user %s from group %s", a.c_str(), b.c_str()); + TCHAR *a = pcli->pfnGetContactDisplayName((MCONTACT)wParam, 0); + TCHAR *b = pcli->pfnGetContactDisplayName((MCONTACT)lParam, 0); + debugLogA("Request remove user %S from group %S", a, b); if (!this->isOnline()) return NULL; DBVARIANT dbv; - if (getString((MCONTACT)lParam, "ID", &dbv)) return NULL; @@ -578,13 +534,11 @@ INT_PTR __cdecl WhatsAppProto::OnRemoveContactFromGroup(WPARAM wParam, LPARAM, L void WhatsAppProto::onOwningGroups(const std::vector& paramVector) { - debugLogA(""); this->HandleReceiveGroups(paramVector, true); } void WhatsAppProto::onParticipatingGroups(const std::vector& paramVector) { - debugLogA(""); this->HandleReceiveGroups(paramVector, false); } @@ -595,41 +549,29 @@ void WhatsAppProto::HandleReceiveGroups(const std::vector& groups, bool // This could take long time if there are many new groups which aren't // yet stored to the database. But that should be a rare case - for (std::vector::const_iterator it = groups.begin(); it != groups.end(); ++it) - { + for (std::vector::const_iterator it = groups.begin(); it != groups.end(); ++it) { hContact = this->AddToContactList(*it, 0, false, NULL, true); setByte(hContact, "IsGroupMember", 1); - if (isOwned) - { + if (isOwned) { this->isMemberByGroupContact[hContact]; // []-operator creates entry, if it doesn't exist setByte(hContact, "SimpleChatRoom", 2); this->connection->sendGetParticipants(*it); } - else - { - isMember[hContact] = true; - } + else isMember[hContact] = true; } // Mark as non-meber if group only exists locally if (!isOwned) - { - for (hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) - { - if (IsMyContact(hContact) && getByte(hContact, "SimpleChatRoom", 0) > 0) - { - //debugLogA("Set IsGroupMember to 0 for '%s'", this->GetContactDisplayName(hContact).c_str()); + for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) + if (!isChatRoom(hContact) && getByte(hContact, "SimpleChatRoom", 0) > 0) setByte(hContact, "IsGroupMember", isMember.find(hContact) == isMember.end() ? 0 : 1); - } - } - } } void WhatsAppProto::onGroupCreated(const std::string& paramString1, const std::string& paramString2) { // Must be received after onOwningGroups() :/ debugLogA("%s / %s", paramString1.c_str(), paramString2.c_str()); - string jid = paramString2 +string("@")+ paramString1; + string jid = paramString2 + string("@") + paramString1; MCONTACT hContact = this->AddToContactList(jid, 0, false, NULL, true); setByte(hContact, "SimpleChatRoom", 2); } @@ -637,7 +579,6 @@ void WhatsAppProto::onGroupCreated(const std::string& paramString1, const std::s // Menu-handler INT_PTR __cdecl WhatsAppProto::OnCreateGroup(WPARAM wParam, LPARAM lParam) { - debugLogA(""); input_box* ib = new input_box; ib->defaultValue = _T(""); ib->limit = WHATSAPP_GROUP_NAME_LIMIT; @@ -645,8 +586,7 @@ INT_PTR __cdecl WhatsAppProto::OnCreateGroup(WPARAM wParam, LPARAM lParam) ib->text = _T("Enter group subject"); ib->title = _T("WhatsApp - Create Group"); ib->thread = &WhatsAppProto::SendCreateGroupWorker; - HWND hDlg = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_INPUTBOX), 0, WhatsAppInputBoxProc, - reinterpret_cast(ib)); + HWND hDlg = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_INPUTBOX), 0, WhatsAppInputBoxProc, LPARAM(ib)); ShowWindow(hDlg, SW_SHOW); return FALSE; } @@ -657,8 +597,7 @@ void __cdecl WhatsAppProto::SendSetGroupNameWorker(void* data) string groupName(ibr->value); mir_free(ibr->value); DBVARIANT dbv; - if (!getString(*((MCONTACT*)ibr->userData), WHATSAPP_KEY_ID, &dbv) && this->isOnline()) - { + if (!getString(*((MCONTACT*)ibr->userData), WHATSAPP_KEY_ID, &dbv) && this->isOnline()) { this->connection->sendSetNewSubject(dbv.pszVal, groupName); db_free(&dbv); } @@ -672,48 +611,40 @@ void __cdecl WhatsAppProto::SendCreateGroupWorker(void* data) string groupName(ibr->value); mir_free(ibr->value); if (this->isOnline()) - { this->connection->sendCreateGroupChat(groupName); - } } -INT_PTR __cdecl WhatsAppProto::OnChangeGroupSubject(WPARAM wParam, LPARAM lParam) +INT_PTR __cdecl WhatsAppProto::OnChangeGroupSubject(WPARAM hContact, LPARAM lParam) { - DBVARIANT dbv; - MCONTACT hContact = MCONTACT(wParam); input_box* ib = new input_box; + DBVARIANT dbv; if (getTString(hContact, WHATSAPP_KEY_PUSH_NAME, &dbv)) ib->defaultValue = _T(""); - else - { + else { ib->defaultValue = dbv.ptszVal; db_free(&dbv); } ib->limit = WHATSAPP_GROUP_NAME_LIMIT; ib->text = _T("Enter new group subject"); ib->title = _T("WhatsApp - Change Group Subject"); - ib->thread = &WhatsAppProto::SendSetGroupNameWorker; ib->proto = this; MCONTACT *hContactPtr = new MCONTACT(hContact); ib->userData = (void*)hContactPtr; - - HWND hDlg = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_INPUTBOX), 0, WhatsAppInputBoxProc, - reinterpret_cast(ib)); + + HWND hDlg = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_INPUTBOX), 0, WhatsAppInputBoxProc, LPARAM(ib)); ShowWindow(hDlg, SW_SHOW); return 0; } -INT_PTR __cdecl WhatsAppProto::OnLeaveGroup(WPARAM wParam, LPARAM) +INT_PTR __cdecl WhatsAppProto::OnLeaveGroup(WPARAM hContact, LPARAM) { DBVARIANT dbv; - MCONTACT hContact = MCONTACT(wParam); - if (this->isOnline() && !getString(hContact, WHATSAPP_KEY_ID, &dbv)) - { + if (this->isOnline() && !getString(hContact, WHATSAPP_KEY_ID, &dbv)) { setByte(hContact, "IsGroupMember", 0); this->connection->sendLeaveGroup(dbv.pszVal); db_free(&dbv); } return 0; -} \ No newline at end of file +} diff --git a/protocols/WhatsApp/src/definitions.h b/protocols/WhatsApp/src/definitions.h index 4817f56a98..7f8f8a7222 100644 --- a/protocols/WhatsApp/src/definitions.h +++ b/protocols/WhatsApp/src/definitions.h @@ -4,13 +4,10 @@ #define FLAG_CONTAINS(x,y) ( ( x & y ) == y ) #define REMOVE_FLAG(x,y) ( x = ( x & ~y )) -#define CODE_BLOCK_TRY try { -#define CODE_BLOCK_CATCH(ex) } catch (ex& e) { debugLogA("Exception: %s", e.what()); -#define CODE_BLOCK_CATCH_UNKNOWN } catch (...) { debugLogA("Unknown exception"); -#define CODE_BLOCK_CATCH_ALL } catch (WAException& e) { debugLogA("Exception: %s", e.what()); \ - } catch (exception& e) { debugLogA("Exception: %s", e.what()); \ - } catch (...) { debugLogA("Unknown exception"); } -#define CODE_BLOCK_END } +#define CODE_BLOCK_CATCH_ALL \ + catch (WAException& e) { debugLogA("Exception: %s", e.what()); \ + } catch (exception& e) { debugLogA("Exception: %s", e.what()); \ + } catch (...) { debugLogA("Unknown exception"); } #define NIIF_INTERN_TCHAR NIIF_INTERN_UNICODE diff --git a/protocols/WhatsApp/src/dialogs.cpp b/protocols/WhatsApp/src/dialogs.cpp index 8f64d55894..95d0006eb6 100644 --- a/protocols/WhatsApp/src/dialogs.cpp +++ b/protocols/WhatsApp/src/dialogs.cpp @@ -9,105 +9,86 @@ INT_PTR CALLBACK WhatsAppAccountProc(HWND hwnd, UINT message, WPARAM wparam, LPA TranslateDialogDefault(hwnd); proto = reinterpret_cast(lparam); - SetWindowLongPtr(hwnd,GWLP_USERDATA,lparam); - SendDlgItemMessage(hwnd, IDC_REG_CODE_1, EM_LIMITTEXT, 3, 0); - SendDlgItemMessage(hwnd, IDC_REG_CODE_2, EM_LIMITTEXT, 3, 0); + SetWindowLongPtr(hwnd, GWLP_USERDATA, lparam); + SendDlgItemMessage(hwnd, IDC_PW, EM_LIMITTEXT, 6, 0); CheckDlgButton(hwnd, IDC_SSL, db_get_b(NULL, proto->ModuleName(), WHATSAPP_KEY_SSL, 0)); DBVARIANT dbv; - if ( !db_get_s(0,proto->ModuleName(),WHATSAPP_KEY_CC,&dbv,DBVT_ASCIIZ)) - { - SetDlgItemTextA(hwnd,IDC_CC,dbv.pszVal); + if (!db_get_s(0, proto->ModuleName(), WHATSAPP_KEY_CC, &dbv, DBVT_ASCIIZ)) { + SetDlgItemTextA(hwnd, IDC_CC, dbv.pszVal); db_free(&dbv); } - if ( !db_get_s(0,proto->ModuleName(),WHATSAPP_KEY_LOGIN,&dbv,DBVT_ASCIIZ)) - { - SetDlgItemTextA(hwnd,IDC_LOGIN,dbv.pszVal); + if (!db_get_s(0, proto->ModuleName(), WHATSAPP_KEY_LOGIN, &dbv, DBVT_ASCIIZ)) { + SetDlgItemTextA(hwnd, IDC_LOGIN, dbv.pszVal); db_free(&dbv); } - if ( !db_get_s(0,proto->ModuleName(),WHATSAPP_KEY_NICK,&dbv,DBVT_ASCIIZ)) - { - SetDlgItemTextA(hwnd,IDC_NICK,dbv.pszVal); + if (!db_get_s(0, proto->ModuleName(), WHATSAPP_KEY_NICK, &dbv, DBVT_ASCIIZ)) { + SetDlgItemTextA(hwnd, IDC_NICK, dbv.pszVal); db_free(&dbv); } - if ( !db_get_s(0,proto->ModuleName(),WHATSAPP_KEY_PASS,&dbv,DBVT_ASCIIZ)) - { - SetDlgItemTextA(hwnd,IDC_PW,dbv.pszVal); - db_free(&dbv); - } + EnableWindow(GetDlgItem(hwnd, IDC_PW), FALSE); if (!proto->isOffline()) { - SendMessage(GetDlgItem(hwnd, IDC_CC), EM_SETREADONLY, 1, 0); - SendMessage(GetDlgItem(hwnd, IDC_LOGIN), EM_SETREADONLY, 1, 0); - SendMessage(GetDlgItem(hwnd, IDC_NICK), EM_SETREADONLY, 1, 0); - SendMessage(GetDlgItem(hwnd, IDC_PW), EM_SETREADONLY, 1, 0); + SendDlgItemMessage(hwnd, IDC_CC, EM_SETREADONLY, 1, 0); + SendDlgItemMessage(hwnd, IDC_LOGIN, EM_SETREADONLY, 1, 0); + SendDlgItemMessage(hwnd, IDC_NICK, EM_SETREADONLY, 1, 0); + SendDlgItemMessage(hwnd, IDC_PW, EM_SETREADONLY, 1, 0); EnableWindow(GetDlgItem(hwnd, IDC_SSL), FALSE); } return TRUE; case WM_COMMAND: - if (LOWORD(wparam) == IDC_BUTTON_REQUEST_CODE || LOWORD(wparam) == IDC_BUTTON_REGISTER) - { - proto = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); + if (LOWORD(wparam) == IDC_BUTTON_REQUEST_CODE || LOWORD(wparam) == IDC_BUTTON_REGISTER) { + proto = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); char cc[5]; GetDlgItemTextA(hwnd, IDC_CC, cc, sizeof(cc)); char number[128]; GetDlgItemTextA(hwnd, IDC_LOGIN, number, sizeof(number)); - if (LOWORD(wparam) == IDC_BUTTON_REQUEST_CODE) - { + if (LOWORD(wparam) == IDC_BUTTON_REQUEST_CODE) { if (MessageBox(NULL, TranslateT("An SMS with registration-code will be sent to your mobile phone.\nNotice that you are not able to use the real WhatsApp and this plugin simultaneously!\nContinue?"), - PRODUCT_NAME, MB_YESNO) == IDYES) - { - proto->Register(REG_STATE_REQ_CODE, string(cc), string(number), string()); + PRODUCT_NAME, MB_YESNO) == IDYES) { + string res = proto->Register(REG_STATE_REQ_CODE, string(cc), string(number), string()); + if (!res.empty()) + EnableWindow(GetDlgItem(hwnd, IDC_PW), TRUE); } } - else if (LOWORD(wparam) == IDC_BUTTON_REGISTER) - { - char code[7]; - if (SendDlgItemMessage(hwnd, IDC_REG_CODE_1, WM_GETTEXTLENGTH, 0, 0) == 3 && - SendDlgItemMessage(hwnd, IDC_REG_CODE_2, WM_GETTEXTLENGTH, 0, 0) == 3) - { - GetDlgItemTextA(hwnd, IDC_REG_CODE_1, code, 4); - GetDlgItemTextA(hwnd, IDC_REG_CODE_2, &(code[3]), 4); - } - else - { - MessageBox(NULL, TranslateT("Please correctly specify your registration code received by SMS"), + else if (LOWORD(wparam) == IDC_BUTTON_REGISTER) { + char code[100]; + GetDlgItemTextA(hwnd, IDC_PW, code, sizeof(code)); + + if (strlen(code) != 6) { + MessageBox(NULL, TranslateT("Please correctly specify your registration code received by SMS"), PRODUCT_NAME, MB_ICONEXCLAMATION); return TRUE; } string pw = proto->Register(REG_STATE_REG_CODE, string(cc), string(number), string(code)); - if (!pw.empty()) - { + if (!pw.empty()) { proto->setString(WHATSAPP_KEY_PASS, pw.c_str()); MessageBox(NULL, TranslateT("Your password has been set automatically.\nIf you change your password manually, you may lose it and need to request a new code!"), PRODUCT_NAME, MB_ICONWARNING); } } } - if ( HIWORD( wparam ) == EN_CHANGE && reinterpret_cast(lparam) == GetFocus()) - { - switch(LOWORD(wparam)) - { + if (HIWORD(wparam) == EN_CHANGE && reinterpret_cast(lparam) == GetFocus()) { + switch (LOWORD(wparam)) { case IDC_CC: case IDC_LOGIN: case IDC_NICK: case IDC_SSL: case IDC_PW: - SendMessage(GetParent(hwnd) ,PSM_CHANGED, 0, 0); + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); } } break; case WM_NOTIFY: - if (reinterpret_cast(lparam)->code == PSN_APPLY) - { + if (reinterpret_cast(lparam)->code == PSN_APPLY) { proto = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); char str[128]; @@ -121,10 +102,6 @@ INT_PTR CALLBACK WhatsAppAccountProc(HWND hwnd, UINT message, WPARAM wparam, LPA db_set_s(0, proto->ModuleName(), WHATSAPP_KEY_NICK, str); db_set_b(0, proto->ModuleName(), WHATSAPP_KEY_SSL, IsDlgButtonChecked(hwnd, IDC_SSL)); - - GetDlgItemTextA(hwnd,IDC_PW,str,sizeof(str)); - db_set_s(0,proto->ModuleName(),WHATSAPP_KEY_PASS,str); - return TRUE; } break; @@ -134,56 +111,43 @@ INT_PTR CALLBACK WhatsAppAccountProc(HWND hwnd, UINT message, WPARAM wparam, LPA return FALSE; } -INT_PTR CALLBACK WhatsAppInputBoxProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) +INT_PTR CALLBACK WhatsAppInputBoxProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { input_box* ib; - switch(message) - { - + switch (message) { case WM_INITDIALOG: - { TranslateDialogDefault(hwnd); ib = reinterpret_cast(lparam); - SetWindowLongPtr(hwnd,GWLP_USERDATA,lparam); - SendDlgItemMessage(hwnd,IDC_VALUE,EM_LIMITTEXT,ib->limit,0); + SetWindowLongPtr(hwnd, GWLP_USERDATA, lparam); + SendDlgItemMessage(hwnd, IDC_VALUE, EM_LIMITTEXT, ib->limit, 0); SetDlgItemText(hwnd, IDC_VALUE, ib->defaultValue.c_str()); SetDlgItemText(hwnd, IDC_TEXT, ib->text.c_str()); - /* - DBVARIANT dbv = { DBVT_TCHAR }; - if (!DBGetContactSettingTString(NULL,ib->proto->m_szModuleName,WHATSAPP_KEY_PUSH_NAME,&dbv)) - { - SetWindowText( hwnd, dbv.ptszVal ); - db_free( &dbv ); - } - */ SetWindowText(hwnd, ib->title.c_str()); - } - EnableWindow(GetDlgItem( hwnd, IDC_OK ), FALSE); - return TRUE; + EnableWindow(GetDlgItem(hwnd, IDC_OK), FALSE); + return TRUE; case WM_COMMAND: - if ( LOWORD( wparam ) == IDC_VALUE && HIWORD( wparam ) == EN_CHANGE ) - { - ib = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); - size_t len = SendDlgItemMessage(hwnd,IDC_VALUE,WM_GETTEXTLENGTH,0,0); + if (LOWORD(wparam) == IDC_VALUE && HIWORD(wparam) == EN_CHANGE) { + ib = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); + size_t len = SendDlgItemMessage(hwnd, IDC_VALUE, WM_GETTEXTLENGTH, 0, 0); TCHAR str[4]; mir_sntprintf(str, 4, TEXT("%d"), ib->limit - len); //SetDlgItemText(hwnd,IDC_CHARACTERS,str); - EnableWindow(GetDlgItem( hwnd, IDC_OK ), len > 0); + EnableWindow(GetDlgItem(hwnd, IDC_OK), len > 0); return TRUE; } - else if ( LOWORD( wparam ) == IDC_OK ) - { - ib = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); - TCHAR* value = new TCHAR[ib->limit+1]; + + if (LOWORD(wparam) == IDC_OK) { + ib = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); + TCHAR* value = new TCHAR[ib->limit + 1]; - GetDlgItemText(hwnd,IDC_VALUE,value, ib->limit + 1); - ShowWindow(hwnd,SW_HIDE); + GetDlgItemText(hwnd, IDC_VALUE, value, ib->limit + 1); + ShowWindow(hwnd, SW_HIDE); input_box_ret* ret = new input_box_ret; ret->userData = ib->userData; @@ -194,15 +158,14 @@ INT_PTR CALLBACK WhatsAppInputBoxProc( HWND hwnd, UINT message, WPARAM wparam, L delete ib; return TRUE; } - else if ( LOWORD( wparam ) == IDC_CANCEL ) - { + + if (LOWORD(wparam) == IDC_CANCEL) { EndDialog(hwnd, wparam); - ib = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); + ib = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); delete ib; return TRUE; } break; - } return FALSE; diff --git a/protocols/WhatsApp/src/dialogs.h b/protocols/WhatsApp/src/dialogs.h index 8b34cd0854..3284755496 100644 --- a/protocols/WhatsApp/src/dialogs.h +++ b/protocols/WhatsApp/src/dialogs.h @@ -1,7 +1,7 @@ #if !defined(DIALOGS_H) #define DIALOGS_H -INT_PTR CALLBACK WhatsAppAccountProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ); -INT_PTR CALLBACK WhatsAppInputBoxProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ); +INT_PTR CALLBACK WhatsAppAccountProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); +INT_PTR CALLBACK WhatsAppInputBoxProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); #endif \ No newline at end of file diff --git a/protocols/WhatsApp/src/entities.h b/protocols/WhatsApp/src/entities.h index 2be8cacd54..7cf037792e 100644 --- a/protocols/WhatsApp/src/entities.h +++ b/protocols/WhatsApp/src/entities.h @@ -3,9 +3,10 @@ struct send_direct { - send_direct(MCONTACT hContact,const std::string &msg, HANDLE msgid, bool isChat = false) - : hContact(hContact), msg(msg), msgid(msgid) - {} + send_direct(MCONTACT hContact, const std::string &msg, HANDLE msgid, bool isChat = false) : + hContact(hContact), msg(msg), msgid(msgid) + {} + MCONTACT hContact; std::string msg; HANDLE msgid; @@ -13,29 +14,28 @@ struct send_direct struct send_typing { - send_typing(MCONTACT hContact,const int status) : hContact(hContact), status(status) {} + send_typing(MCONTACT hContact, const int status) : hContact(hContact), status(status) {} MCONTACT hContact; int status; }; struct input_box { - tstring text; - tstring title; - tstring defaultValue; - int limit; - - void (__cdecl WhatsAppProto::*thread)(void*); - WhatsAppProto* proto; - void* userData; + tstring text; + tstring title; + tstring defaultValue; + int limit; + + void(__cdecl WhatsAppProto::*thread)(void*); + WhatsAppProto *proto; + void *userData; }; struct input_box_ret // has to be deleted by input-box handler { - void* userData; // has to be deleted by input-box handler - char* value; // mir_free() has to be called by input-box handler + void *userData; // has to be deleted by input-box handler + char *value; // mir_free() has to be called by input-box handler }; - #endif // ENTITIES_H \ No newline at end of file diff --git a/protocols/WhatsApp/src/main.cpp b/protocols/WhatsApp/src/main.cpp index 58897c86cc..9bc53ce6de 100644 --- a/protocols/WhatsApp/src/main.cpp +++ b/protocols/WhatsApp/src/main.cpp @@ -1,11 +1,9 @@ #include "common.h" -CLIST_INTERFACE* pcli; +CLIST_INTERFACE *pcli; int hLangpack; HINSTANCE g_hInstance; -std::string g_strUserAgent; -DWORD g_mirandaVersion; PLUGININFOEX pluginInfo = { sizeof(PLUGININFOEX), @@ -22,140 +20,9 @@ PLUGININFOEX pluginInfo = { }; -BOOL IsRunAsAdmin() -{ - BOOL fIsRunAsAdmin = FALSE; - DWORD dwError = ERROR_SUCCESS; - PSID pAdministratorsGroup = NULL; - - // Allocate and initialize a SID of the administrators group. - SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; - if ( !AllocateAndInitializeSid( - &NtAuthority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, - &pAdministratorsGroup)) - { - dwError = GetLastError(); - goto Cleanup; - } - - // Determine whether the SID of administrators group is enabled in - // the primary access token of the process. - if ( !CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin)) - { - dwError = GetLastError(); - goto Cleanup; - } - -Cleanup: - // Centralized cleanup for all allocated resources. - if (pAdministratorsGroup) - { - FreeSid(pAdministratorsGroup); - pAdministratorsGroup = NULL; - } - - // Throw the error if something failed in the function. - if (ERROR_SUCCESS != dwError) - { - throw dwError; - } - - return fIsRunAsAdmin; -} - -int UnpackRegisterUtility(HINSTANCE hInstance, const wchar_t *profileName) -{ - wchar_t fileName[MAX_PATH]; - ::GetModuleFileName(hInstance, fileName, MAX_PATH); - - wchar_t *RegisterUtilityPath = ::wcsrchr(fileName, '\\'); - if (RegisterUtilityPath != NULL) - *RegisterUtilityPath = 0; - ::mir_snwprintf(fileName, SIZEOF(fileName), L"%s\\%s", fileName, L"WART-1.7.1.0.exe"); - if ( ::GetFileAttributes(fileName) == DWORD(-1)) - { - HRSRC hRes = ::FindResource(hInstance, MAKEINTRESOURCE(IDR_REGISTERUTILITY), L"BIN"); - if (hRes) - { - HGLOBAL hResource = ::LoadResource(hInstance, hRes); - if (hResource) - { - HANDLE hFile; - char *pData = (char *)LockResource(hResource); - DWORD dwSize = SizeofResource(hInstance, hRes), written = 0; - if ((hFile = ::CreateFile( - fileName, - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - 0)) != INVALID_HANDLE_VALUE) - { - ::WriteFile(hFile, (void *)pData, dwSize, &written, NULL); - ::CloseHandle(hFile); - } - else - { - // Check the current process's "run as administrator" status. - // Elevate the process if it is not run as administrator. - if (!IsRunAsAdmin()) - { - wchar_t path[MAX_PATH], cmdLine[100]; - ::GetModuleFileName(NULL, path, ARRAYSIZE(path)); - - if (profileName) - ::mir_snwprintf( - cmdLine, - SIZEOF(cmdLine), - L" /restart:%d /profile=%s", - ::GetCurrentProcessId(), - profileName); - else - ::mir_snwprintf( - cmdLine, - SIZEOF(cmdLine), - L" /restart:%d", - ::GetCurrentProcessId()); - - // Launch itself as administrator. - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.lpVerb = L"runas"; - sei.lpFile = path; - sei.lpParameters = cmdLine; - //sei.hwnd = hDlg; - sei.nShow = SW_NORMAL; - - if ( !::ShellExecuteEx(&sei)) - { - DWORD dwError = ::GetLastError(); - if (dwError == ERROR_CANCELLED) - { - // The user refused to allow privileges elevation. - // Do nothing ... - } - } - } - else - return 0; - } - } - else - return 0; - } - else - return 0; - } - - return 1; -} - ///////////////////////////////////////////////////////////////////////////// // Protocol instances + static int compare_protos(const WhatsAppProto *p1, const WhatsAppProto *p2) { return _tcscmp(p1->m_tszUserName, p2->m_tszUserName); @@ -163,7 +30,7 @@ static int compare_protos(const WhatsAppProto *p1, const WhatsAppProto *p2) OBJLIST g_Instances(1, compare_protos); -DWORD WINAPI DllMain(HINSTANCE hInstance,DWORD,LPVOID) +DWORD WINAPI DllMain(HINSTANCE hInstance, DWORD, LPVOID) { g_hInstance = hInstance; return TRUE; @@ -171,43 +38,32 @@ DWORD WINAPI DllMain(HINSTANCE hInstance,DWORD,LPVOID) extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { - g_mirandaVersion = mirandaVersion; return &pluginInfo; } ///////////////////////////////////////////////////////////////////////////////////////// // Interface information -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_PROTOCOL, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOCOL, MIID_LAST }; ///////////////////////////////////////////////////////////////////////////////////////// // Load -static PROTO_INTERFACE* protoInit(const char *proto_name,const TCHAR *username ) +static PROTO_INTERFACE* protoInit(const char *proto_name, const TCHAR *username) { - WhatsAppProto *proto = new WhatsAppProto(proto_name,username); + WhatsAppProto *proto = new WhatsAppProto(proto_name, username); g_Instances.insert(proto); return proto; } static int protoUninit(PROTO_INTERFACE* proto) { - g_Instances.remove(( WhatsAppProto* )proto); + g_Instances.remove((WhatsAppProto*)proto); return EXIT_SUCCESS; } -static HANDLE g_hEvents[1]; - extern "C" int __declspec(dllexport) Load(void) { - VARST profilename( _T("%miranda_profilename%")); - - if ( !UnpackRegisterUtility(g_hInstance, (TCHAR *)profilename)) - { - ::MessageBox(NULL, TranslateT("Did not unpack WART (registration utility)."), _T("WhatsApp"), MB_OK | MB_ICONERROR); - return 1; - } - mir_getLP(&pluginInfo); mir_getCLI(); @@ -216,33 +72,16 @@ extern "C" int __declspec(dllexport) Load(void) pd.type = PROTOTYPE_PROTOCOL; pd.fnInit = protoInit; pd.fnUninit = protoUninit; - CallService(MS_PROTO_REGISTERMODULE,0,reinterpret_cast(&pd)); + CallService(MS_PROTO_REGISTERMODULE, 0, reinterpret_cast(&pd)); InitIcons(); //InitContactMenus(); // Init native User-Agent - { - std::stringstream agent; -// DWORD mir_ver = ( DWORD )CallService( MS_SYSTEM_GETVERSION, NULL, NULL ); - agent << "MirandaNG/"; - agent << (( g_mirandaVersion >> 24) & 0xFF); - agent << "."; - agent << (( g_mirandaVersion >> 16) & 0xFF); - agent << "."; - agent << (( g_mirandaVersion >> 8) & 0xFF); - agent << "."; - agent << (( g_mirandaVersion ) & 0xFF); - #ifdef _WIN64 - agent << " WhatsApp Protocol x64/"; - #else - agent << " WhatsApp Protocol/"; - #endif - agent << __VERSION_STRING; - g_strUserAgent = agent.str( ); - } + WORD v[4]; + CallService(MS_SYSTEM_GETFILEVERSION, 0, LPARAM(&v)); - return 0; + return 0; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -250,10 +89,6 @@ extern "C" int __declspec(dllexport) Load(void) extern "C" int __declspec(dllexport) Unload(void) { - //UninitContactMenus(); - for(size_t i=0; iremote_resource.empty(); std::string* msg; - switch (paramFMessage->media_wa_type) - { + switch (paramFMessage->media_wa_type) { case FMessage::WA_TYPE_IMAGE: case FMessage::WA_TYPE_AUDIO: case FMessage::WA_TYPE_VIDEO: @@ -23,15 +22,14 @@ void WhatsAppProto::onMessageForMe(FMessage* paramFMessage, bool paramBoolean) msg = ¶mFMessage->data; } - if (isChatRoom) - { + if (isChatRoom) { msg->insert(0, std::string("[").append(paramFMessage->notifyname).append("]: ")); } - MCONTACT hContact = this->AddToContactList(paramFMessage->key->remote_jid, 0, false, + MCONTACT hContact = this->AddToContactList(paramFMessage->key->remote_jid, 0, false, isChatRoom ? NULL : paramFMessage->notifyname.c_str(), isChatRoom); - PROTORECVEVENT recv = {0}; + PROTORECVEVENT recv = { 0 }; recv.flags = PREF_UTF; recv.szMessage = const_cast(msg->c_str()); recv.timestamp = paramFMessage->timestamp; //time(NULL); @@ -42,32 +40,29 @@ void WhatsAppProto::onMessageForMe(FMessage* paramFMessage, bool paramBoolean) int WhatsAppProto::SendMsg(MCONTACT hContact, int flags, const char *msg) { - debugLogA(""); + int msgId = ++(this->msgId); - ForkThread( &WhatsAppProto::SendMsgWorker, new send_direct(hContact, msg, (HANDLE) msgId, flags & IS_CHAT)); + ForkThread(&WhatsAppProto::SendMsgWorker, new send_direct(hContact, msg, (HANDLE)msgId, flags & IS_CHAT)); return this->msgIdHeader + msgId; } void WhatsAppProto::SendMsgWorker(void* p) { - debugLogA(""); + if (p == NULL) return; DBVARIANT dbv; send_direct *data = static_cast(p); - if (getByte(data->hContact, "SimpleChatRoom", 0) > 0 && getByte(data->hContact, "IsGroupMember", 0) == 0) - { + if (getByte(data->hContact, "SimpleChatRoom", 0) > 0 && getByte(data->hContact, "IsGroupMember", 0) == 0) { debugLogA("not a group member"); ProtoBroadcastAck(data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, - (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) "You cannot send messages to groups if you are not a member."); + (HANDLE)(this->msgIdHeader + this->msgId), (LPARAM) "You cannot send messages to groups if you are not a member."); } - else if (!getString(data->hContact, "ID", &dbv) && this->connection != NULL) - { - try - { + else if (!getString(data->hContact, "ID", &dbv) && this->connection != NULL) { + try { setDword(data->hContact, WHATSAPP_KEY_LAST_MSG_STATE, 2); setDword(data->hContact, WHATSAPP_KEY_LAST_MSG_ID_HEADER, this->msgIdHeader); setDword(data->hContact, WHATSAPP_KEY_LAST_MSG_ID, this->msgId); @@ -83,24 +78,21 @@ void WhatsAppProto::SendMsgWorker(void* p) this->connection->sendMessage(&fmsg); } - catch (exception &e) - { + catch (exception &e) { debugLogA("exception: %s", e.what()); - ProtoBroadcastAck(data->hContact,ACKTYPE_MESSAGE,ACKRESULT_FAILED, - (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) e.what()); + ProtoBroadcastAck(data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, + (HANDLE)(this->msgIdHeader + this->msgId), (LPARAM)e.what()); } - catch (...) - { + catch (...) { debugLogA("unknown exception"); - ProtoBroadcastAck(data->hContact,ACKTYPE_MESSAGE,ACKRESULT_FAILED, - (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) "Failed sending message"); + ProtoBroadcastAck(data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, + (HANDLE)(this->msgIdHeader + this->msgId), (LPARAM) "Failed sending message"); } } - else - { + else { debugLogA("No connection"); - ProtoBroadcastAck(data->hContact,ACKTYPE_MESSAGE,ACKRESULT_FAILED, - (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) "You cannot send messages when you are offline."); + ProtoBroadcastAck(data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, + (HANDLE)(this->msgIdHeader + this->msgId), (LPARAM) "You cannot send messages when you are offline."); } delete data; @@ -121,16 +113,15 @@ void WhatsAppProto::RecvMsgWorker(void *p) void WhatsAppProto::onIsTyping(const std::string& paramString, bool paramBoolean) { MCONTACT hContact = this->AddToContactList(paramString, 0, false); - if (hContact != NULL) - { - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, (LPARAM) + if (hContact != NULL) { + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM) paramBoolean ? PROTOTYPE_CONTACTTYPING_INFINITE : PROTOTYPE_CONTACTTYPING_OFF); } } -int WhatsAppProto::UserIsTyping(MCONTACT hContact,int type) -{ +int WhatsAppProto::UserIsTyping(MCONTACT hContact, int type) +{ if (hContact && isOnline()) ForkThread(&WhatsAppProto::SendTypingWorker, new send_typing(hContact, type)); @@ -139,31 +130,30 @@ int WhatsAppProto::UserIsTyping(MCONTACT hContact,int type) void WhatsAppProto::SendTypingWorker(void* p) { - if(p == NULL) + if (p == NULL) return; send_typing *typing = static_cast(p); // Don't send typing notifications to contacts which are offline - if ( getWord(typing->hContact, "Status", 0) == ID_STATUS_OFFLINE) + if (getWord(typing->hContact, "Status", 0) == ID_STATUS_OFFLINE) return; DBVARIANT dbv; - if ( !getString(typing->hContact, WHATSAPP_KEY_ID,&dbv) && - this->isOnline()) - { + if (!getString(typing->hContact, WHATSAPP_KEY_ID, &dbv) && + this->isOnline()) { if (typing->status == PROTOTYPE_SELFTYPING_ON) this->connection->sendComposing(dbv.pszVal); else this->connection->sendPaused(dbv.pszVal); - } + } delete typing; } void WhatsAppProto::onMessageStatusUpdate(FMessage* fmsg) { - debugLogA(""); + MCONTACT hContact = this->ContactIDToHContact(fmsg->key->remote_jid); if (hContact == 0) @@ -176,21 +166,20 @@ void WhatsAppProto::onMessageStatusUpdate(FMessage* fmsg) int header; int id; size_t delimPos = fmsg->key->id.find("-"); - + std::stringstream ss; ss << fmsg->key->id.substr(0, delimPos); ss >> header; - + ss.clear(); ss << fmsg->key->id.substr(delimPos + 1); ss >> id; if (state == 1) - ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE) (header + id),0); + ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)(header + id), 0); - if (getDword(hContact, WHATSAPP_KEY_LAST_MSG_ID_HEADER, 0) == header && getDword(hContact, WHATSAPP_KEY_LAST_MSG_ID, -1) == id) - { + if (getDword(hContact, WHATSAPP_KEY_LAST_MSG_ID_HEADER, 0) == header && getDword(hContact, WHATSAPP_KEY_LAST_MSG_ID, -1) == id) { setDword(hContact, WHATSAPP_KEY_LAST_MSG_STATE, state); this->UpdateStatusMsg(hContact); } -} \ No newline at end of file +} diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp index 4b142f0d47..634ac19c05 100644 --- a/protocols/WhatsApp/src/proto.cpp +++ b/protocols/WhatsApp/src/proto.cpp @@ -1,9 +1,11 @@ #include "common.h" +#include "WhatsAPI++\WARegister.h" + WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) : PROTO(proto_name, username) { - this->challenge = new std::vector; + this->challenge = new std::vector < unsigned char > ; this->msgId = 0; this->msgIdHeader = time(NULL); @@ -22,20 +24,18 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) : // Create standard network connection TCHAR descr[512]; - NETLIBUSER nlu = {sizeof(nlu)}; + NETLIBUSER nlu = { sizeof(nlu) }; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; - char module[512]; - mir_snprintf(module, SIZEOF(module), "%s", m_szModuleName); - nlu.szSettingsModule = module; + nlu.szSettingsModule = m_szModuleName; mir_sntprintf(descr, SIZEOF(descr), TranslateT("%s server connection"), m_tszUserName); nlu.ptszDescriptiveName = descr; - m_hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); + m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); if (m_hNetlibUser == NULL) MessageBox(NULL, TranslateT("Unable to get Netlib connection for WhatsApp"), m_tszUserName, MB_OK); WASocketConnection::initNetwork(m_hNetlibUser); - def_avatar_folder_ = std::tstring( VARST( _T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName; + def_avatar_folder_ = std::tstring(VARST(_T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName; SetAllContactStatuses(ID_STATUS_OFFLINE, true); } @@ -61,51 +61,40 @@ int WhatsAppProto::OnModulesLoaded(WPARAM wParam, LPARAM lParam) return 0; } -DWORD_PTR WhatsAppProto::GetCaps( int type, MCONTACT hContact ) +DWORD_PTR WhatsAppProto::GetCaps(int type, MCONTACT hContact) { - switch(type) - { - case PFLAGNUM_1: - { - DWORD_PTR flags = PF1_IM | PF1_CHAT | PF1_BASICSEARCH | PF1_ADDSEARCHRES; - return flags | PF1_MODEMSGRECV; // #TODO - } - case PFLAGNUM_2: - return PF2_ONLINE | PF2_INVISIBLE; - case PFLAGNUM_3: - return 0; - case PFLAGNUM_4: - return PF4_NOCUSTOMAUTH | PF4_IMSENDUTF | PF4_FORCEADDED | PF4_NOAUTHDENYREASON | PF4_IMSENDOFFLINE | PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_AVATARS; - case PFLAGNUM_5: - return 0; - case PFLAG_MAXLENOFMESSAGE: - return 500; // #TODO - case PFLAG_UNIQUEIDTEXT: - return (DWORD_PTR) "WhatsApp ID"; - case PFLAG_UNIQUEIDSETTING: - return (DWORD_PTR) "ID"; + switch (type) { + case PFLAGNUM_1: + return PF1_IM | PF1_CHAT | PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_MODEMSGRECV; + case PFLAGNUM_2: + return PF2_ONLINE | PF2_INVISIBLE; + case PFLAGNUM_3: + return 0; + case PFLAGNUM_4: + return PF4_NOCUSTOMAUTH | PF4_IMSENDUTF | PF4_FORCEADDED | PF4_NOAUTHDENYREASON | PF4_IMSENDOFFLINE | PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_AVATARS; + case PFLAGNUM_5: + return 0; + case PFLAG_MAXLENOFMESSAGE: + return 500; // #TODO + case PFLAG_UNIQUEIDTEXT: + return (DWORD_PTR)"WhatsApp ID"; + case PFLAG_UNIQUEIDSETTING: + return (DWORD_PTR)"ID"; } return 0; } -int WhatsAppProto::SetStatus( int new_status ) +int WhatsAppProto::SetStatus(int new_status) { debugLogA("===== Beginning SetStatus process"); // Routing statuses not supported by WhatsApp - switch ( new_status ) - { + switch (new_status) { case ID_STATUS_INVISIBLE: case ID_STATUS_OFFLINE: m_iDesiredStatus = new_status; break; - /* - case ID_STATUS_CONNECTING: - m_iDesiredStatus = ID_STATUS_OFFLINE; - break; - */ - case ID_STATUS_IDLE: default: m_iDesiredStatus = ID_STATUS_INVISIBLE; @@ -117,19 +106,17 @@ int WhatsAppProto::SetStatus( int new_status ) break; } - if (m_iStatus == ID_STATUS_CONNECTING) - { + if (m_iStatus == ID_STATUS_CONNECTING) { debugLogA("===== Status is connecting, no change"); return 0; } - if (m_iStatus == m_iDesiredStatus) - { + if (m_iStatus == m_iDesiredStatus) { debugLogA("===== Statuses are same, no change"); return 0; } - ForkThread( &WhatsAppProto::ChangeStatus, this ); + ForkThread(&WhatsAppProto::ChangeStatus, this); return 0; } @@ -139,7 +126,7 @@ MCONTACT WhatsAppProto::AddToList(int flags, PROTOSEARCHRESULT* psr) return NULL; } -int WhatsAppProto::AuthRequest(MCONTACT hContact,const PROTOCHAR *message) +int WhatsAppProto::AuthRequest(MCONTACT hContact, const PROTOCHAR *message) { return this->RequestFriendship((WPARAM)hContact, NULL); } @@ -149,7 +136,7 @@ int WhatsAppProto::Authorize(HANDLE hDbEvent) return 1; } -HANDLE WhatsAppProto::SearchBasic( const PROTOCHAR* id ) +HANDLE WhatsAppProto::SearchBasic(const PROTOCHAR* id) { if (isOffline()) return 0; @@ -161,164 +148,143 @@ HANDLE WhatsAppProto::SearchBasic( const PROTOCHAR* id ) ///////////////////////////////////////////////////////////////////////////////////////// -static NETLIBHTTPHEADER s_registerHeaders[] = +static NETLIBHTTPHEADER s_registerHeaders[] = { - { "User-Agent", ACCOUNT_USER_AGENT_REGISTRATION }, - { "Accept", "text/json" }, + { "User-Agent", ACCOUNT_USER_AGENT }, + { "Accept", "text/json" }, { "Content-Type", "application/x-www-form-urlencoded" } }; -string WhatsAppProto::Register(int state, string cc, string number, string code) +string WhatsAppProto::Register(int state, const string &cc, const string &number, const string &code) { string idx; string ret; DBVARIANT dbv; - if ( WASocketConnection::hNetlibUser == NULL) - { + if (WASocketConnection::hNetlibUser == NULL) { NotifyEvent(m_tszUserName, TranslateT("Network-connection error."), NULL, WHATSAPP_EVENT_CLIENT); return ret; } - if ( !getString(WHATSAPP_KEY_IDX, &dbv)) - { + if (!getString(WHATSAPP_KEY_IDX, &dbv)) { idx = dbv.pszVal; db_free(&dbv); } - if (idx.empty()) - { + if (idx.empty()) { std::stringstream tm; tm << time(NULL); BYTE idxBuf[16]; utils::md5string(tm.str(), idxBuf); - idx = std::string((const char*) idxBuf, 16); + idx = std::string((const char*)idxBuf, 16); setString(WHATSAPP_KEY_IDX, idx.c_str()); } - string url; - if (state == REG_STATE_REQ_CODE) - { - unsigned char digest[16]; - utils::md5string(std::string(ACCOUNT_TOKEN_PREFIX1) + ACCOUNT_TOKEN_PREFIX2 + number, digest); - url = string(ACCOUNT_URL_CODEREQUESTV2); - url += "?lc=US&lg=en&mcc=000&mnc=000&method=sms&token=" + Utilities::bytesToHex(digest, 16); - } - else if (state == REG_STATE_REG_CODE) - { - url = string(ACCOUNT_URL_REGISTERREQUESTV2); - url += "?code="+ code; - } - url += "&cc="+ cc +"&in="+ number +"&id="+ idx; + CMStringA url = WARegister::RequestCodeUrl(cc + number, code); + if (url.IsEmpty()) + return ret; - NETLIBHTTPREQUEST nlhr = {sizeof(NETLIBHTTPREQUEST)}; + NETLIBHTTPREQUEST nlhr = { sizeof(NETLIBHTTPREQUEST) }; nlhr.requestType = REQUEST_POST; - nlhr.szUrl = (char*) url.c_str(); + nlhr.szUrl = url.GetBuffer(); nlhr.headers = s_registerHeaders; nlhr.headersCount = SIZEOF(s_registerHeaders); nlhr.flags = NLHRF_HTTP11 | NLHRF_GENERATEHOST | NLHRF_REMOVEHOST | NLHRF_SSL; - NETLIBHTTPREQUEST* pnlhr = (NETLIBHTTPREQUEST*) CallService(MS_NETLIB_HTTPTRANSACTION, - (WPARAM) WASocketConnection::hNetlibUser, (LPARAM)&nlhr); + NETLIBHTTPREQUEST* pnlhr = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, + (WPARAM)WASocketConnection::hNetlibUser, (LPARAM)&nlhr); - string title = this->TranslateStr("Registration"); + const TCHAR *ptszTitle = TranslateT("Registration"); if (pnlhr == NULL) { - this->NotifyEvent(title, this->TranslateStr("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); + this->NotifyEvent(ptszTitle, TranslateT("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); return ret; } debugLogA("Server response: %s", pnlhr->pData); - MessageBoxA(NULL, pnlhr->pData, "Debug", MB_OK); JSONROOT resp(pnlhr->pData); - if (resp == NULL) - { - this->NotifyEvent(title, this->TranslateStr("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); + if (resp == NULL) { + this->NotifyEvent(ptszTitle, TranslateT("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); return ret; } // Status = fail JSONNODE *val = json_get(resp, "status"); - if (!lstrcmp( ptrT(json_as_string(val)), _T("fail"))) - { + if (!lstrcmp(ptrT(json_as_string(val)), _T("fail"))) { JSONNODE *tmpVal = json_get(resp, "reason"); - if (!lstrcmp( ptrT(json_as_string(tmpVal)), _T("stale"))) - this->NotifyEvent(title, this->TranslateStr("Registration failed due to stale code. Please request a new code"), NULL, WHATSAPP_EVENT_CLIENT); + if (!lstrcmp(ptrT(json_as_string(tmpVal)), _T("stale"))) + this->NotifyEvent(ptszTitle, TranslateT("Registration failed due to stale code. Please request a new code"), NULL, WHATSAPP_EVENT_CLIENT); else - this->NotifyEvent(title, this->TranslateStr("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); + this->NotifyEvent(ptszTitle, TranslateT("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); tmpVal = json_get(resp, "retry_after"); - if (tmpVal != NULL) - this->NotifyEvent(title, this->TranslateStr("Please try again in %i seconds", json_as_int(tmpVal)), NULL, WHATSAPP_EVENT_OTHER); + if (tmpVal != NULL) { + CMString tmp(FORMAT, TranslateT("Please try again in %i seconds"), json_as_int(tmpVal)); + this->NotifyEvent(ptszTitle, tmp, NULL, WHATSAPP_EVENT_OTHER); + } + return ret; } // Request code - else if (state == REG_STATE_REQ_CODE) - { - if ( !lstrcmp( ptrT(json_as_string(val)), _T("sent"))) - this->NotifyEvent(title, this->TranslateStr("Registration code has been sent to your phone."), NULL, WHATSAPP_EVENT_OTHER); + if (state == REG_STATE_REQ_CODE) { + if (!lstrcmp(ptrT(json_as_string(val)), _T("sent"))) + this->NotifyEvent(ptszTitle, TranslateT("Registration code has been sent to your phone."), NULL, WHATSAPP_EVENT_OTHER); + return "ok"; } // Register - else if (state == REG_STATE_REG_CODE) - { + if (state == REG_STATE_REG_CODE) { val = json_get(resp, "pw"); if (val == NULL) - this->NotifyEvent(title, this->TranslateStr("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); + this->NotifyEvent(ptszTitle, TranslateT("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); else - ret = _T2A( ptrT(json_as_string(val))); + ret = _T2A(ptrT(json_as_string(val))); } - json_delete(resp); return ret; } ////////////////////////////////////////////////////////////////////////////// // EVENTS -INT_PTR WhatsAppProto::SvcCreateAccMgrUI(WPARAM wParam,LPARAM lParam) +INT_PTR WhatsAppProto::SvcCreateAccMgrUI(WPARAM wParam, LPARAM lParam) { - return (INT_PTR)CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_WHATSAPPACCOUNT), - (HWND)lParam, WhatsAppAccountProc, (LPARAM)this ); + return (INT_PTR)CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_WHATSAPOPTIONS), + (HWND)lParam, WhatsAppAccountProc, (LPARAM)this); } int WhatsAppProto::OnOptionsInit(WPARAM wParam, LPARAM lParam) { - OPTIONSDIALOGPAGE odp = {sizeof(odp)}; - odp.hInstance = g_hInstance; - odp.ptszTitle = m_tszUserName; + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.hInstance = g_hInstance; + odp.ptszTitle = m_tszUserName; odp.dwInitParam = LPARAM(this); - odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_DONTTRANSLATE; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_DONTTRANSLATE; - odp.position = 1; - odp.ptszGroup = LPGENT("Network"); - odp.ptszTab = LPGENT("Account"); + odp.position = 1; + odp.ptszGroup = LPGENT("Network"); + odp.ptszTab = LPGENT("Account"); odp.pszTemplate = MAKEINTRESOURCEA(IDD_WHATSAPOPTIONS); - odp.pfnDlgProc = WhatsAppAccountProc; + odp.pfnDlgProc = WhatsAppAccountProc; Options_AddPage(wParam, &odp); return 0; } -int WhatsAppProto::RefreshBuddyList(WPARAM, LPARAM ) +int WhatsAppProto::RefreshBuddyList(WPARAM, LPARAM) { - debugLogA(""); - if (!isOffline()) - { + if (!isOffline()) { //ForkThread( } return 0; } -int WhatsAppProto::RequestFriendship(WPARAM wParam, LPARAM lParam) +int WhatsAppProto::RequestFriendship(WPARAM hContact, LPARAM lParam) { - if (wParam == NULL || isOffline()) + if (hContact == NULL || isOffline()) return 0; - MCONTACT hContact = MCONTACT(wParam); - DBVARIANT dbv; - if ( !getString(hContact, WHATSAPP_KEY_ID, &dbv)) - { + if (!getString(hContact, WHATSAPP_KEY_ID, &dbv)) { std::string id(dbv.pszVal); this->connection->sendQueryLastOnline(id); this->connection->sendPresenceSubscriptionRequest(id); @@ -335,29 +301,20 @@ std::tstring WhatsAppProto::GetAvatarFolder() LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch(message) - { + switch (message) { case WM_COMMAND: - { // After a click, destroy popup PUDeletePopup(hwnd); - } - break; + break; case WM_CONTEXTMENU: PUDeletePopup(hwnd); break; case UM_FREEPLUGINDATA: - { // After close, free - TCHAR* url = (TCHAR*)PUGetPluginData(hwnd); - if (url != NULL) - mir_free(url); - } return FALSE; - - default: - break; + mir_free(PUGetPluginData(hwnd)); + return FALSE; } return DefWindowProc(hwnd, message, wParam, lParam); @@ -365,49 +322,44 @@ LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa void WhatsAppProto::NotifyEvent(const string& title, const string& info, MCONTACT contact, DWORD flags, TCHAR* url) { - TCHAR* rawTitle = mir_a2t_cp(title.c_str(), CP_UTF8); - TCHAR* rawInfo = mir_a2t_cp(info.c_str(), CP_UTF8); + TCHAR *rawTitle = mir_a2t_cp(title.c_str(), CP_UTF8); + TCHAR *rawInfo = mir_a2t_cp(info.c_str(), CP_UTF8); this->NotifyEvent(rawTitle, rawInfo, contact, flags, url); mir_free(rawTitle); mir_free(rawInfo); } -void WhatsAppProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWORD flags, TCHAR* szUrl) +void WhatsAppProto::NotifyEvent(const TCHAR *title, const TCHAR *info, MCONTACT contact, DWORD flags, TCHAR* szUrl) { int ret; int timeout; COLORREF colorBack = 0; COLORREF colorText = 0; - switch ( flags ) - { - case WHATSAPP_EVENT_CLIENT: - if ( !getByte( WHATSAPP_KEY_EVENT_CLIENT_ENABLE, DEFAULT_EVENT_CLIENT_ENABLE )) - goto exit; - if ( !getByte( WHATSAPP_KEY_EVENT_CLIENT_DEFAULT, 0 )) - { - colorBack = getDword( WHATSAPP_KEY_EVENT_CLIENT_COLBACK, DEFAULT_EVENT_COLBACK ); - colorText = getDword( WHATSAPP_KEY_EVENT_CLIENT_COLTEXT, DEFAULT_EVENT_COLTEXT ); - } - timeout = getDword( WHATSAPP_KEY_EVENT_CLIENT_TIMEOUT, 0 ); - flags |= NIIF_WARNING; - break; + switch (flags) { + case WHATSAPP_EVENT_CLIENT: + if (!getByte(WHATSAPP_KEY_EVENT_CLIENT_ENABLE, DEFAULT_EVENT_CLIENT_ENABLE)) + goto exit; + if (!getByte(WHATSAPP_KEY_EVENT_CLIENT_DEFAULT, 0)) { + colorBack = getDword(WHATSAPP_KEY_EVENT_CLIENT_COLBACK, DEFAULT_EVENT_COLBACK); + colorText = getDword(WHATSAPP_KEY_EVENT_CLIENT_COLTEXT, DEFAULT_EVENT_COLTEXT); + } + timeout = getDword(WHATSAPP_KEY_EVENT_CLIENT_TIMEOUT, 0); + flags |= NIIF_WARNING; + break; - case WHATSAPP_EVENT_OTHER: - if ( !getByte( WHATSAPP_KEY_EVENT_OTHER_ENABLE, DEFAULT_EVENT_OTHER_ENABLE )) - goto exit; - if ( !getByte( WHATSAPP_KEY_EVENT_OTHER_DEFAULT, 0 )) - { - colorBack = getDword( WHATSAPP_KEY_EVENT_OTHER_COLBACK, DEFAULT_EVENT_COLBACK ); - colorText = getDword( WHATSAPP_KEY_EVENT_OTHER_COLTEXT, DEFAULT_EVENT_COLTEXT ); - } - timeout = getDword( WHATSAPP_KEY_EVENT_OTHER_TIMEOUT, -1 ); - SkinPlaySound( "OtherEvent" ); - flags |= NIIF_INFO; - break; + case WHATSAPP_EVENT_OTHER: + if (!getByte(WHATSAPP_KEY_EVENT_OTHER_ENABLE, DEFAULT_EVENT_OTHER_ENABLE)) + goto exit; + if (!getByte(WHATSAPP_KEY_EVENT_OTHER_DEFAULT, 0)) { + colorBack = getDword(WHATSAPP_KEY_EVENT_OTHER_COLBACK, DEFAULT_EVENT_COLBACK); + colorText = getDword(WHATSAPP_KEY_EVENT_OTHER_COLTEXT, DEFAULT_EVENT_COLTEXT); + } + timeout = getDword(WHATSAPP_KEY_EVENT_OTHER_TIMEOUT, -1); + SkinPlaySound("OtherEvent"); + flags |= NIIF_INFO; + break; } - if ( !getByte(WHATSAPP_KEY_SYSTRAY_NOTIFY,DEFAULT_SYSTRAY_NOTIFY)) - { - if (ServiceExists(MS_POPUP_ADDPOPUP)) - { + if (!getByte(WHATSAPP_KEY_SYSTRAY_NOTIFY, DEFAULT_SYSTRAY_NOTIFY)) { + if (ServiceExists(MS_POPUP_ADDPOPUP)) { POPUPDATAT pd; pd.colorBack = colorBack; pd.colorText = colorText; @@ -423,21 +375,19 @@ void WhatsAppProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWO if (ret == 0) return; } - } else { - if (ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) - { + } + else { + if (ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) { MIRANDASYSTRAYNOTIFY err; int niif_flags = flags; - REMOVE_FLAG( niif_flags, WHATSAPP_EVENT_CLIENT | - WHATSAPP_EVENT_NOTIFICATION | - WHATSAPP_EVENT_OTHER ); + REMOVE_FLAG(niif_flags, WHATSAPP_EVENT_CLIENT | WHATSAPP_EVENT_NOTIFICATION | WHATSAPP_EVENT_OTHER); err.szProto = m_szModuleName; err.cbSize = sizeof(err); err.dwInfoFlags = NIIF_INTERN_TCHAR | niif_flags; - err.tszInfoTitle = title; - err.tszInfo = info; + err.tszInfoTitle = (TCHAR*)title; + err.tszInfo = (TCHAR*)info; err.uTimeout = 1000 * timeout; - ret = CallService(MS_CLIST_SYSTRAY_NOTIFY, 0, (LPARAM) & err); + ret = CallService(MS_CLIST_SYSTRAY_NOTIFY, 0, (LPARAM)& err); if (ret == 0) goto exit; @@ -451,12 +401,3 @@ exit: if (szUrl != NULL) mir_free(szUrl); } - -string WhatsAppProto::TranslateStr(const char* str, ...) -{ - va_list ap; - va_start(ap, str); - string ret = Utilities::string_format(Translate(str), ap); - va_end(ap); - return ret; -} \ No newline at end of file diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index aa8483bd02..8963735320 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -9,25 +9,25 @@ public: WhatsAppProto(const char *proto_name, const TCHAR *username); ~WhatsAppProto( ); - inline const char* ModuleName( ) const + inline const char* ModuleName() const { return m_szModuleName; } - inline bool isOnline( ) + inline bool isOnline() { - return ( m_iStatus != ID_STATUS_OFFLINE && m_iStatus != ID_STATUS_CONNECTING && - connection != NULL ); + return (m_iStatus != ID_STATUS_OFFLINE && m_iStatus != ID_STATUS_CONNECTING && + connection != NULL); } - inline bool isOffline( ) + inline bool isOffline() { - return ( m_iStatus == ID_STATUS_OFFLINE ); + return (m_iStatus == ID_STATUS_OFFLINE); } - inline bool isInvisible( ) + inline bool isInvisible() { - return ( m_iStatus == ID_STATUS_INVISIBLE ); + return (m_iStatus == ID_STATUS_INVISIBLE); } //PROTO_INTERFACE @@ -35,176 +35,174 @@ public: virtual MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT* psr); virtual MCONTACT __cdecl AddToListByEvent(int flags, int iContact, HANDLE hDbEvent) { return NULL; } - virtual int __cdecl Authorize( HANDLE hDbEvent ); - virtual int __cdecl AuthDeny( HANDLE hDbEvent, const PROTOCHAR* szReason ) { return 1; } - virtual int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT* ) { return 1; } - virtual int __cdecl AuthRequest(MCONTACT hContact, const PROTOCHAR* szMessage ); + virtual int __cdecl Authorize(HANDLE hDbEvent); + virtual int __cdecl AuthDeny(HANDLE hDbEvent, const PROTOCHAR* szReason) { return 1; } + virtual int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT*) { return 1; } + virtual int __cdecl AuthRequest(MCONTACT hContact, const PROTOCHAR* szMessage); - virtual HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* szPath ) { return NULL; } - virtual int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer ) { return 1; } - virtual int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* szReason ) { return 1; } - virtual int __cdecl FileResume( HANDLE hTransfer, int* action, const PROTOCHAR** szFilename ) { return 1; } + virtual HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* szPath) { return NULL; } + virtual int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer) { return 1; } + virtual int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* szReason) { return 1; } + virtual int __cdecl FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** szFilename) { return 1; } - virtual DWORD_PTR __cdecl GetCaps( int type, MCONTACT hContact = NULL ); - virtual int __cdecl GetInfo(MCONTACT hContact, int infoType ) { return 1; } + virtual DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact = NULL); + virtual int __cdecl GetInfo(MCONTACT hContact, int infoType) { return 1; } - virtual HANDLE __cdecl SearchBasic( const PROTOCHAR* id ); - virtual HANDLE __cdecl SearchByEmail( const PROTOCHAR* email ) { return NULL; } - virtual HANDLE __cdecl SearchByName( const PROTOCHAR* nick, const PROTOCHAR* firstName, const PROTOCHAR* lastName ) { return NULL; } - virtual HWND __cdecl SearchAdvanced( HWND owner ) { return NULL; } - virtual HWND __cdecl CreateExtendedSearchUI( HWND owner ) { return NULL; } + virtual HANDLE __cdecl SearchBasic(const PROTOCHAR* id); + virtual HANDLE __cdecl SearchByEmail(const PROTOCHAR* email) { return NULL; } + virtual HANDLE __cdecl SearchByName(const PROTOCHAR* nick, const PROTOCHAR* firstName, const PROTOCHAR* lastName) { return NULL; } + virtual HWND __cdecl SearchAdvanced(HWND owner) { return NULL; } + virtual HWND __cdecl CreateExtendedSearchUI(HWND owner) { return NULL; } - virtual int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT* ) { return 1; } - virtual int __cdecl RecvFile(MCONTACT hContact, PROTOFILEEVENT* ) { return 1; } - virtual int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT* ); - virtual int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT* ) { return 1; } + virtual int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT*) { return 1; } + virtual int __cdecl RecvFile(MCONTACT hContact, PROTOFILEEVENT*) { return 1; } + virtual int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT*); + virtual int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT*) { return 1; } virtual int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList) { return 1; } - virtual HANDLE __cdecl SendFile(MCONTACT hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles ) { return NULL; } - virtual int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg ); - virtual int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url ) { return 1; } + virtual HANDLE __cdecl SendFile(MCONTACT hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles) { return NULL; } + virtual int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg); + virtual int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url) { return 1; } - virtual int __cdecl SetApparentMode(MCONTACT hContact, int mode ) { return 1; } - virtual int __cdecl SetStatus( int iNewStatus ); + virtual int __cdecl SetApparentMode(MCONTACT hContact, int mode) { return 1; } + virtual int __cdecl SetStatus(int iNewStatus); - virtual HANDLE __cdecl GetAwayMsg(MCONTACT hContact ) { return NULL; } - virtual int __cdecl RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT* evt ) { return 1; } - virtual int __cdecl SendAwayMsg(MCONTACT hContact, HANDLE hProcess, const char* msg ) { return 1; } - virtual int __cdecl SetAwayMsg( int iStatus, const PROTOCHAR* msg ) { return 1; } + virtual HANDLE __cdecl GetAwayMsg(MCONTACT hContact) { return NULL; } + virtual int __cdecl RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT* evt) { return 1; } + virtual int __cdecl SendAwayMsg(MCONTACT hContact, HANDLE hProcess, const char* msg) { return 1; } + virtual int __cdecl SetAwayMsg(int iStatus, const PROTOCHAR* msg) { return 1; } - virtual int __cdecl UserIsTyping(MCONTACT hContact, int type ); + virtual int __cdecl UserIsTyping(MCONTACT hContact, int type); - virtual int __cdecl OnEvent( PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam ) { return 1; } + virtual int __cdecl OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam) { return 1; } //////////////////////// - // Services - INT_PTR __cdecl SvcCreateAccMgrUI( WPARAM, LPARAM); + // Services + INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM); INT_PTR __cdecl OnJoinChat(WPARAM, LPARAM); INT_PTR __cdecl OnLeaveChat(WPARAM, LPARAM); - INT_PTR __cdecl OnCreateGroup(WPARAM,LPARAM); + INT_PTR __cdecl OnCreateGroup(WPARAM, LPARAM); int __cdecl OnOptionsInit(WPARAM, LPARAM); int __cdecl OnModulesLoaded(WPARAM, LPARAM); - + int __cdecl RefreshBuddyList(WPARAM, LPARAM); - int __cdecl RequestFriendship(WPARAM, LPARAM); - - // Events - int __cdecl OnBuildStatusMenu(WPARAM,LPARAM); - int __cdecl OnChatOutgoing(WPARAM,LPARAM); - int __cdecl OnPrebuildContactMenu(WPARAM,LPARAM); - - INT_PTR __cdecl OnAddContactToGroup(WPARAM, LPARAM, LPARAM); - INT_PTR __cdecl OnRemoveContactFromGroup(WPARAM, LPARAM, LPARAM); - INT_PTR __cdecl OnChangeGroupSubject(WPARAM, LPARAM); - INT_PTR __cdecl OnLeaveGroup(WPARAM, LPARAM); - - // Loops - bool NegotiateConnection(); - void __cdecl stayConnectedLoop(void*); - void __cdecl sentinelLoop(void*); - - // Processing Threads - void __cdecl ProcessBuddyList(void*); - void __cdecl SearchAckThread(void*); - - // Worker Threads - void __cdecl ChangeStatus(void*); - void __cdecl SendMsgWorker(void*); - void __cdecl RecvMsgWorker(void*); - void __cdecl SendTypingWorker(void*); - void __cdecl SendGetGroupInfoWorker(void*); - void __cdecl SendSetGroupNameWorker(void*); - void __cdecl SendCreateGroupWorker(void*); - - // Contacts handling - MCONTACT AddToContactList(const std::string& jid, BYTE type = 0, bool dont_check = false, - const char *new_name = NULL, bool isChatRoom = false, bool isHidden = false); + int __cdecl RequestFriendship(WPARAM, LPARAM); + + // Events + int __cdecl OnBuildStatusMenu(WPARAM, LPARAM); + int __cdecl OnChatOutgoing(WPARAM, LPARAM); + int __cdecl OnPrebuildContactMenu(WPARAM, LPARAM); + + INT_PTR __cdecl OnAddContactToGroup(WPARAM, LPARAM, LPARAM); + INT_PTR __cdecl OnRemoveContactFromGroup(WPARAM, LPARAM, LPARAM); + INT_PTR __cdecl OnChangeGroupSubject(WPARAM, LPARAM); + INT_PTR __cdecl OnLeaveGroup(WPARAM, LPARAM); + + // Loops + bool NegotiateConnection(); + void __cdecl stayConnectedLoop(void*); + void __cdecl sentinelLoop(void*); + + // Processing Threads + void __cdecl ProcessBuddyList(void*); + void __cdecl SearchAckThread(void*); + + // Worker Threads + void __cdecl ChangeStatus(void*); + void __cdecl SendMsgWorker(void*); + void __cdecl RecvMsgWorker(void*); + void __cdecl SendTypingWorker(void*); + void __cdecl SendGetGroupInfoWorker(void*); + void __cdecl SendSetGroupNameWorker(void*); + void __cdecl SendCreateGroupWorker(void*); + + // Contacts handling + MCONTACT AddToContactList(const std::string &jid, BYTE type = 0, bool dont_check = false, + const char *new_name = NULL, bool isChatRoom = false, bool isHidden = false); bool IsMyContact(MCONTACT hContact, bool include_chat = false); MCONTACT ContactIDToHContact(const std::string&); - void SetAllContactStatuses(int status, bool reset_client = false); - void UpdateStatusMsg(MCONTACT hContact); - string GetContactDisplayName(MCONTACT hContact); - string GetContactDisplayName(const string& jid); - void InitContactMenus(); - void HandleReceiveGroups(const std::vector& groups, bool isOwned); - + void SetAllContactStatuses(int status, bool reset_client = false); + void UpdateStatusMsg(MCONTACT hContact); + TCHAR* GetContactDisplayName(const string &jid); + void InitContactMenus(); + void HandleReceiveGroups(const std::vector &groups, bool isOwned); + bool IsGroupChat(MCONTACT hC, bool checkIsAdmin = false) - { + { return getByte(hC, "SimpleChatRoom", 0) > (checkIsAdmin ? 1 : 0); - } + } - // Registration - string Register(int state, string cc, string number, string code); + // Registration + string Register(int state, const string &cc, const string &number, const string &code); - // Helpers - std::tstring GetAvatarFolder(); - void ToggleStatusMenuItems( BOOL bEnable ); - string TranslateStr(const char* str, ...); + // Helpers + std::tstring GetAvatarFolder(); + void ToggleStatusMenuItems(BOOL bEnable); - // Handles, Locks + // Handles, Locks HGENMENU m_hMenuRoot; HANDLE m_hMenuCreateGroup; - HANDLE signon_lock_; - HANDLE log_lock_; - HANDLE update_loop_lock_; + HANDLE signon_lock_; + HANDLE log_lock_; + HANDLE update_loop_lock_; - std::tstring def_avatar_folder_; + std::tstring def_avatar_folder_; - WASocketConnection* conn; - WAConnection* connection; - Mutex connMutex; - int lastPongTime; + WASocketConnection* conn; + WAConnection* connection; + Mutex connMutex; + int lastPongTime; - std::vector* challenge; - int msgId; - int msgIdHeader; - string phoneNumber; - string jid; - string nick; + std::vector* challenge; + int msgId; + int msgIdHeader; + string phoneNumber; + string jid; + string nick; std::map hContactByJid; map> isMemberByGroupContact; - // WhatsApp Events - virtual void onMessageForMe(FMessage* paramFMessage, bool paramBoolean); - virtual void onMessageStatusUpdate(FMessage* paramFMessage); - virtual void onMessageError(FMessage* message, int paramInt) { debugLogA(""); } - virtual void onPing(const std::string& id) throw (WAException); - virtual void onPingResponseReceived() { debugLogA(""); } - virtual void onAvailable(const std::string& paramString, bool paramBoolean); - virtual void onClientConfigReceived(const std::string& paramString) { debugLogA(""); } - virtual void onLastSeen(const std::string& paramString1, int paramInt, std::string* paramString2); - virtual void onIsTyping(const std::string& paramString, bool paramBoolean); - virtual void onAccountChange(int paramInt, time_t expire_date) { debugLogA(""); } - virtual void onPrivacyBlockListAdd(const std::string& paramString) { debugLogA(""); } - virtual void onPrivacyBlockListClear() { debugLogA(""); } - virtual void onDirty(const std::map& paramHashtable) { debugLogA(""); } - virtual void onDirtyResponse(int paramHashtable) { debugLogA(""); } - virtual void onRelayRequest(const std::string& paramString1, int paramInt, const std::string& paramString2) { debugLogA(""); } - virtual void onSendGetPictureIds(std::map* ids); - virtual void onSendGetPicture(const std::string& jid, const std::vector& data, const std::string& oldId, const std::string& newId); - virtual void onPictureChanged(const std::string& from, const std::string& author, bool set); - virtual void onDeleteAccount(bool result) { debugLogA(""); } + // WhatsApp Events + virtual void onMessageForMe(FMessage* paramFMessage, bool paramBoolean); + virtual void onMessageStatusUpdate(FMessage* paramFMessage); + virtual void onMessageError(FMessage* message, int paramInt) { ; } + virtual void onPing(const std::string& id) throw (WAException); + virtual void onPingResponseReceived() { } + virtual void onAvailable(const std::string& paramString, bool paramBoolean); + virtual void onClientConfigReceived(const std::string& paramString) { } + virtual void onLastSeen(const std::string& paramString1, int paramInt, std::string* paramString2); + virtual void onIsTyping(const std::string& paramString, bool paramBoolean); + virtual void onAccountChange(int paramInt, time_t expire_date) { } + virtual void onPrivacyBlockListAdd(const std::string& paramString) { } + virtual void onPrivacyBlockListClear() { } + virtual void onDirty(const std::map& paramHashtable) { } + virtual void onDirtyResponse(int paramHashtable) { } + virtual void onRelayRequest(const std::string& paramString1, int paramInt, const std::string& paramString2) { } + virtual void onSendGetPictureIds(std::map* ids); + virtual void onSendGetPicture(const std::string& jid, const std::vector& data, const std::string& oldId, const std::string& newId); + virtual void onPictureChanged(const std::string& from, const std::string& author, bool set); + virtual void onDeleteAccount(bool result) { } virtual void onGroupAddUser(const std::string& paramString1, const std::string& paramString2); virtual void onGroupRemoveUser(const std::string& paramString1, const std::string& paramString2); virtual void onGroupNewSubject(const std::string& from, const std::string& author, const std::string& newSubject, int paramInt); - virtual void onServerProperties(std::map* nameValueMap) { debugLogA(""); } + virtual void onServerProperties(std::map* nameValueMap) { } virtual void onGroupCreated(const std::string& paramString1, const std::string& paramString2); virtual void onGroupInfo(const std::string& paramString1, const std::string& paramString2, const std::string& paramString3, const std::string& paramString4, int paramInt1, int paramInt2); virtual void onGroupInfoFromList(const std::string& paramString1, const std::string& paramString2, const std::string& paramString3, const std::string& paramString4, int paramInt1, int paramInt2); virtual void onOwningGroups(const std::vector& paramVector); - virtual void onSetSubject(const std::string& paramString) { debugLogA(""); } - virtual void onAddGroupParticipants(const std::string& paramString, const std::vector& paramVector, int paramHashtable) { debugLogA(""); } - virtual void onRemoveGroupParticipants(const std::string& paramString, const std::vector& paramVector, int paramHashtable) { debugLogA(""); } + virtual void onSetSubject(const std::string& paramString) { } + virtual void onAddGroupParticipants(const std::string& paramString, const std::vector& paramVector, int paramHashtable) { } + virtual void onRemoveGroupParticipants(const std::string& paramString, const std::vector& paramVector, int paramHashtable) { } virtual void onGetParticipants(const std::string& gjid, const std::vector& participants); virtual void onParticipatingGroups(const std::vector& paramVector); virtual void onLeaveGroup(const std::string& paramString); // Information providing - void NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWORD flags, TCHAR* url = NULL); - void NotifyEvent(const string& title, const string& info, MCONTACT contact, DWORD flags, TCHAR* url = NULL); + void NotifyEvent(const TCHAR *title, const TCHAR *info, MCONTACT contact, DWORD flags, TCHAR *url = NULL); + void NotifyEvent(const string &title, const string &info, MCONTACT contact, DWORD flags, TCHAR *url = NULL); }; #endif \ No newline at end of file diff --git a/protocols/WhatsApp/src/resource.h b/protocols/WhatsApp/src/resource.h index 764ea8dd5f..41454c3199 100644 --- a/protocols/WhatsApp/src/resource.h +++ b/protocols/WhatsApp/src/resource.h @@ -1,8 +1,7 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by whatsapp.rc +// Used by d:\miranda-ng\protocols\WhatsApp\res\whatsapp.rc // -#define IDD_WHATSAPPACCOUNT 101 #define IDD_INPUTBOX 102 #define IDR_REGISTERUTILITY 103 #define IDD_WHATSAPOPTIONS 104 @@ -24,10 +23,6 @@ #define IDC_CANCEL 1011 #define IDC_OK 1012 #define IDC_TEXT 1014 -#define IDC_REG_CODE_1 1015 -#define IDC_REG_CODE_2 1016 -#define IDC_REG_CODE_3 1017 -#define IDC_REG_CODE_4 1018 // Next default values for new objects // diff --git a/protocols/WhatsApp/src/theme.cpp b/protocols/WhatsApp/src/theme.cpp index 3597084672..3376291af0 100644 --- a/protocols/WhatsApp/src/theme.cpp +++ b/protocols/WhatsApp/src/theme.cpp @@ -106,7 +106,7 @@ int WhatsAppProto::OnPrebuildContactMenu(WPARAM wParam,LPARAM lParam) { MCONTACT hContact = MCONTACT(wParam); if (hContact) - debugLogA(this->GetContactDisplayName(hContact).c_str()); + debugLog(pcli->pfnGetContactDisplayName(hContact, 0)); else debugLogA("No contact found"); @@ -153,11 +153,10 @@ int WhatsAppProto::OnPrebuildContactMenu(WPARAM wParam,LPARAM lParam) { fullSvcName = svcName + dbv.pszVal; mi.pszService = (char*) fullSvcName.c_str(); - mi.ptszName = mir_a2t_cp(this->GetContactDisplayName(it->first).c_str(), CP_UTF8); + mi.ptszName = pcli->pfnGetContactDisplayName(it->first, 0); CreateServiceFunctionParam(mi.pszService, GlobalServiceParam<&WhatsAppProto::OnAddContactToGroup>, (LPARAM) it->first); Menu_AddContactMenuItem(&mi); db_free(&dbv); - mir_free(mi.ptszName); iGrpCount++; } } @@ -205,12 +204,11 @@ int WhatsAppProto::OnPrebuildContactMenu(WPARAM wParam,LPARAM lParam) { fullSvcName = svcName + dbv.pszVal; mi.pszService = (char*) fullSvcName.c_str(); - mi.ptszName = mir_a2t_cp(this->GetContactDisplayName(it->first).c_str(), CP_UTF8); + mi.ptszName = pcli->pfnGetContactDisplayName(it->first, 0); CreateServiceFunctionParam(mi.pszService, GlobalServiceParam<&WhatsAppProto::OnRemoveContactFromGroup>, (LPARAM) it->first); Menu_AddContactMenuItem(&mi); db_free(&dbv); - mir_free(mi.ptszName); bShow = true; } } @@ -227,7 +225,7 @@ int WhatsAppProto::OnPrebuildContactMenu(WPARAM wParam,LPARAM lParam) int WhatsAppProto::OnBuildStatusMenu(WPARAM wParam, LPARAM lParam) { - debugLogA(""); + char text[200]; strcpy(text, m_szModuleName); char *tDest = text + strlen(text); diff --git a/protocols/WhatsApp/src/utils.cpp b/protocols/WhatsApp/src/utils.cpp index 9559fb3372..35d3ceb3a6 100644 --- a/protocols/WhatsApp/src/utils.cpp +++ b/protocols/WhatsApp/src/utils.cpp @@ -1,55 +1,5 @@ #include "common.h" -void UnixTimeToFileTime(time_t t, LPFILETIME pft) -{ - // Note that LONGLONG is a 64-bit value - LONGLONG ll; - - ll = Int32x32To64(t, 10000000) + 116444736000000000; - pft->dwLowDateTime = (DWORD)ll; - pft->dwHighDateTime = ll >> 32; -} - -DWORD utils::conversion::to_timestamp(std::string data) -{ - DWORD timestamp = NULL; - /* - if (!utils::conversion::from_string(timestamp, data, std::dec)) { - timestamp = static_cast(::time(NULL)); - } - */ - return timestamp; -} - -std::string utils::text::source_get_value(std::string* data, unsigned int argument_count, ...) -{ - va_list arg; - std::string ret; - std::string::size_type start = 0, end = 0; - - va_start(arg, argument_count); - - for (unsigned int i = argument_count; i > 0; i--) - { - if (i == 1) - { - end = data->find(va_arg(arg, char*), start); - if (start == std::string::npos || end == std::string::npos) - break; - ret = data->substr(start, end - start); - } else { - std::string term = va_arg(arg, char*); - start = data->find(term, start); - if (start == std::string::npos) - break; - start += term.length(); - } - } - - va_end(arg); - return ret; -} - std::string getLastErrorMsg() { // Retrieve the system error message for the last-error code @@ -67,43 +17,11 @@ std::string getLastErrorMsg() (LPSTR) &lpMsgBuf, 0, NULL ); - // Display the error message and exit the process - /* - lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); - StringCchPrintf((LPTSTR)lpDisplayBuf, - LocalSize(lpDisplayBuf) / sizeof(TCHAR), - TEXT("%s"), - lpMsgBuf); - */ - std::string ret((LPSTR) lpMsgBuf); LocalFree(lpMsgBuf); - //LocalFree(lpDisplayBuf); - - //return std::string((LPCTSTR)lpDisplayBuf); return ret; } -int utils::debug::log(std::string file_name, std::string text) -{ - char szFile[MAX_PATH]; - GetModuleFileNameA(g_hInstance, szFile, SIZEOF(szFile)); - std::string path = szFile; - path = path.substr(0, path.rfind("\\")); - path = path.substr(0, path.rfind("\\") + 1); - path = path + file_name.c_str() + ".txt"; - - SYSTEMTIME time; - GetLocalTime(&time); - - std::ofstream out(path.c_str(), std::ios_base::out | std::ios_base::app | std::ios_base::ate); - out << "[" << (time.wHour < 10 ? "0" : "") << time.wHour << ":" << (time.wMinute < 10 ? "0" : "") << time.wMinute << ":" << (time.wSecond < 10 ? "0" : "") << time.wSecond << "] " << text << std::endl; - out.close(); - - return EXIT_SUCCESS; -} - BYTE* utils::md5string(const BYTE *data, int size, BYTE *digest) { mir_md5_state_t md5_state; @@ -118,10 +36,10 @@ BYTE* utils::md5string(const BYTE *data, int size, BYTE *digest) std::string base64_encode(void* pData, size_t len) { - return (char*)ptrA( mir_base64_encode((BYTE*)pData, (unsigned)len)); + return (char*)ptrA(mir_base64_encode((BYTE*)pData, (unsigned)len)); } -void md5_string(const std::string& data, BYTE digest[16]) +void md5_string(const std::string &data, BYTE digest[16]) { utils::md5string(data, digest); } diff --git a/protocols/WhatsApp/src/utils.h b/protocols/WhatsApp/src/utils.h index ece8dafaf3..a5b1e17592 100644 --- a/protocols/WhatsApp/src/utils.h +++ b/protocols/WhatsApp/src/utils.h @@ -8,11 +8,11 @@ class ScopedLock public: ScopedLock(HANDLE h, int t = INFINITE) : handle_(h), timeout_(t) { - WaitForSingleObject(handle_,timeout_); + WaitForSingleObject(handle_, timeout_); } ~ScopedLock() { - if(handle_) + if (handle_) ReleaseMutex(handle_); } void Unlock() @@ -28,57 +28,39 @@ private: class Mutex : public IMutex { private: - HANDLE handle; + HANDLE handle; public: - Mutex() : handle(NULL) {} + Mutex() : handle(NULL) {} - virtual ~Mutex() - { - if (this->handle != NULL) - { - ReleaseMutex(this->handle); - } - } + virtual ~Mutex() + { + if (this->handle != NULL) { + ReleaseMutex(this->handle); + } + } - virtual void lock() - { - if (this->handle == NULL) - { - this->handle = CreateMutex(NULL, FALSE, NULL); - } - } + virtual void lock() + { + if (this->handle == NULL) { + this->handle = CreateMutex(NULL, FALSE, NULL); + } + } - virtual void unlock() - { - ReleaseMutex(this->handle); - this->handle = NULL; - } + virtual void unlock() + { + ReleaseMutex(this->handle); + this->handle = NULL; + } }; std::string getLastErrorMsg(); -void UnixTimeToFileTime(time_t t, LPFILETIME pft); - namespace utils { - namespace debug - { - int log(std::string file_name, std::string text); - }; - - namespace conversion - { - DWORD to_timestamp( std::string data ); - }; - - namespace text - { - std::string source_get_value(std::string* data, unsigned int argument_count, ...); - }; - BYTE* md5string(const BYTE*, int, BYTE* digest); - __forceinline BYTE* md5string(const std::string& str, BYTE* digest) { + __forceinline BYTE* md5string(const std::string &str, BYTE* digest) + { return md5string((BYTE*)str.data(), (int)str.length(), digest); } }; diff --git a/protocols/WhatsApp/src/version.h b/protocols/WhatsApp/src/version.h index 18378f4a9d..97ccdcfe90 100644 --- a/protocols/WhatsApp/src/version.h +++ b/protocols/WhatsApp/src/version.h @@ -1,6 +1,6 @@ #define __MAJOR_VERSION 0 -#define __MINOR_VERSION 0 -#define __RELEASE_NUM 2 +#define __MINOR_VERSION 1 +#define __RELEASE_NUM 0 #define __BUILD_NUM 1 #include -- cgit v1.2.3