#pragma once #include "skype.h" #include struct CSkypeProto; typedef void (__cdecl CSkypeProto::* SkypeThreadFunc) (void*); typedef INT_PTR (__cdecl CSkypeProto::* SkypeServiceFunc)(WPARAM, LPARAM); typedef int (__cdecl CSkypeProto::* SkypeEventFunc)(WPARAM, LPARAM); typedef INT_PTR (__cdecl CSkypeProto::* SkypeServiceFuncParam)(WPARAM, LPARAM, LPARAM); struct StringList : public LIST { static int compare(const char* p1, const char* p2) { return _stricmp(p1, p2); } StringList() : LIST(2, compare) {} StringList(const char* string, const char *delimeters) : LIST(2, compare) { char *data = ::mir_strdup(string); if (data) { char *p = ::strtok(data, delimeters); if (p) { this->insert(::mir_strdup(p)); while (p = strtok(NULL, delimeters)) { this->insert(::mir_strdup(p)); } } ::mir_free(data); } } ~StringList() { destroy(); } void destroy( void ) { for (int i=0; i < count; i++) mir_free(items[i]); List_Destroy((SortedList*)this); } int insertn(const char* p) { return insert(mir_strdup(p)); } int remove(int idx) { mir_free(items[idx]); return List_Remove((SortedList*)this, idx); } int remove(const char* p) { int idx; return List_GetIndex((SortedList*)this, (char*)p, &idx) == 1 ? remove(idx) : -1; } bool contains(char* p) { int idx; return List_GetIndex((SortedList*)this, (char*)p, &idx) == 1; } }; struct _tag_iconList { wchar_t* Description; char* Name; int IconId; HANDLE Handle; }; struct LanguagesListEntry { const char *szName; char ISOcode[3]; }; #define LI_STRING 0 #define LI_LIST 1 #define LI_NUMBER 2 struct SettingItem { const TCHAR *szDescription; const char *szDbSetting; int dbType; //DBVT_ constant unsigned displayType; //LI_ constant }; const SettingItem setting[]={ {LPGENT("Full name"), "Nick", DBVT_WCHAR, LI_STRING}, {LPGENT("Mood"), "XStatusMsg", DBVT_WCHAR, LI_STRING}, {LPGENT("Mobile phone"), "Cellular", DBVT_WCHAR, LI_NUMBER}, {LPGENT("Home phone"), "Phone", DBVT_WCHAR, LI_NUMBER}, {LPGENT("Office phone"), "CompanyPhone", DBVT_WCHAR, LI_NUMBER}, {LPGENT("E-mail 1"), "e-mail0", DBVT_WCHAR, LI_STRING}, {LPGENT("E-mail 2"), "e-mail1", DBVT_WCHAR, LI_STRING}, {LPGENT("E-mail 3"), "e-mail2", DBVT_WCHAR, LI_STRING}, {LPGENT("Country"), "Country", DBVT_WCHAR, LI_LIST}, {LPGENT("State"), "State", DBVT_WCHAR, LI_STRING}, {LPGENT("City"), "City", DBVT_WCHAR, LI_STRING}, {LPGENT("Time zone"), "Timezone", DBVT_BYTE, LI_LIST}, {LPGENT("Homepage"), "Homepage", DBVT_WCHAR, LI_STRING}, {LPGENT("Gender"), "Gender", DBVT_BYTE, LI_LIST}, {LPGENT("Birth day"), "BirthDay", DBVT_BYTE, LI_NUMBER}, {LPGENT("Birth month"), "BirthMonth", DBVT_BYTE, LI_NUMBER}, {LPGENT("Birth year"), "BirthYear", DBVT_WORD, LI_NUMBER}, {LPGENT("Language"), "Language1", DBVT_WCHAR, LI_LIST}, {LPGENT("About"), "About", DBVT_WCHAR, LI_STRING} }; struct HtmlEntity { const char *entity; char symbol; }; const HtmlEntity htmlEntities[]={ {"nbsp", ' '}, {"amp", '&'}, {"quot", '"'}, {"lt", '<'}, {"gt", '>'}, {"apos", '\''}, {"copy", '©'}, // TODO: add more }; struct InviteChatParam { char *id; HANDLE hContact; CSkypeProto *ppro; InviteChatParam(const char *id, HANDLE hContact, CSkypeProto *ppro) : id(::mir_strdup(id)), hContact(hContact), ppro(ppro) {} ~InviteChatParam() { ::mir_free(id); } }; struct PasswordRequestBoxParam { char *login; char *password; bool rememberPassword; bool showRememberPasswordBox; PasswordRequestBoxParam(const char *login, bool showRememberPasswordBox = true, bool rememberPassword = false) : login(::mir_strdup(login)), password(NULL), rememberPassword(rememberPassword), showRememberPasswordBox(showRememberPasswordBox) { } ~PasswordRequestBoxParam() { if (login) ::mir_free(login); if (password) ::mir_free(password); } }; struct PasswordChangeBoxParam { char *password; char *password2; PasswordChangeBoxParam() { } ~PasswordChangeBoxParam() { if (password) ::mir_free(password); if (password2) ::mir_free(password2); } }; struct CSkypeProto : public PROTO_INTERFACE, public MZeroedObject { public: CSkypeProto(const char *, const wchar_t *); ~CSkypeProto(); // PROTO_INTERFACE virtual HANDLE __cdecl AddToList( int flags, PROTOSEARCHRESULT* psr ); virtual HANDLE __cdecl AddToListByEvent( int flags, int iContact, HANDLE hDbEvent ); virtual int __cdecl Authorize( HANDLE hDbEvent ); virtual int __cdecl AuthDeny( HANDLE hDbEvent, const TCHAR* szReason ); virtual int __cdecl AuthRecv( HANDLE hContact, PROTORECVEVENT* ); virtual int __cdecl AuthRequest( HANDLE hContact, const TCHAR* szMessage ); virtual HANDLE __cdecl ChangeInfo( int iInfoType, void* pInfoData ); virtual HANDLE __cdecl FileAllow( HANDLE hContact, HANDLE hTransfer, const TCHAR* szPath ); virtual int __cdecl FileCancel( HANDLE hContact, HANDLE hTransfer ); virtual int __cdecl FileDeny( HANDLE hContact, HANDLE hTransfer, const TCHAR* szReason ); virtual int __cdecl FileResume( HANDLE hTransfer, int* action, const TCHAR** szFilename ); virtual DWORD_PTR __cdecl GetCaps( int type, HANDLE hContact = NULL ); virtual HICON __cdecl GetIcon( int iconIndex ); virtual int __cdecl GetInfo( HANDLE hContact, int infoType ); virtual HANDLE __cdecl SearchBasic( const TCHAR* id ); virtual HANDLE __cdecl SearchByEmail( const TCHAR* email ); virtual HANDLE __cdecl SearchByName( const TCHAR* nick, const TCHAR* firstName, const TCHAR* lastName ); virtual HWND __cdecl SearchAdvanced( HWND owner ); virtual HWND __cdecl CreateExtendedSearchUI( HWND owner ); virtual int __cdecl RecvContacts( HANDLE hContact, PROTORECVEVENT* ); virtual int __cdecl RecvFile( HANDLE hContact, PROTORECVFILET* ); virtual int __cdecl RecvMsg( HANDLE hContact, PROTORECVEVENT* ); virtual int __cdecl RecvUrl( HANDLE hContact, PROTORECVEVENT* ); virtual int __cdecl SendContacts( HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList ); virtual HANDLE __cdecl SendFile( HANDLE hContact, const TCHAR* szDescription, TCHAR** ppszFiles ); virtual int __cdecl SendMsg( HANDLE hContact, int flags, const char* msg ); virtual int __cdecl SendUrl( HANDLE hContact, int flags, const char* url ); virtual int __cdecl SetApparentMode( HANDLE hContact, int mode ); virtual int __cdecl SetStatus( int iNewStatus ); virtual HANDLE __cdecl GetAwayMsg( HANDLE hContact ); virtual int __cdecl RecvAwayMsg( HANDLE hContact, int mode, PROTORECVEVENT* evt ); virtual int __cdecl SendAwayMsg( HANDLE hContact, HANDLE hProcess, const char* msg ); virtual int __cdecl SetAwayMsg( int m_iStatus, const TCHAR* msg ); virtual int __cdecl UserIsTyping( HANDLE hContact, int type ); virtual int __cdecl OnEvent( PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam ); virtual int __cdecl RequestAuth(WPARAM, LPARAM); virtual int __cdecl GrantAuth(WPARAM, LPARAM); virtual int __cdecl RevokeAuth(WPARAM, LPARAM); // events int __cdecl OnModulesLoaded(WPARAM, LPARAM); int __cdecl OnPreShutdown(WPARAM, LPARAM); int __cdecl OnContactDeleted(WPARAM, LPARAM); int __cdecl OnOptionsInit(WPARAM, LPARAM); int __cdecl OnUserInfoInit(WPARAM, LPARAM); INT_PTR __cdecl OnAccountManagerInit(WPARAM wParam, LPARAM lParam); // instances static CSkypeProto* InitSkypeProto(const char* protoName, const wchar_t* userName); static int UninitSkypeProto(CSkypeProto* ppro); // services static void InitServiceList(); // icons static void InitIcons(); static void UninitIcons(); static HANDLE GetIconHandle(const char *name); // menus void OnInitStatusMenu(); static void InitMenus(); static void UninitMenus(); INT_PTR __cdecl InviteCommand(WPARAM, LPARAM); static CSkypeProto* GetInstanceByHContact(HANDLE hContact); static int PrebuildContactMenu(WPARAM wParam, LPARAM lParam); bool IsOnline(); protected: DWORD dwCMDNum; CSkype *skype; CAccount::Ref account; CContact::Refs contactList; CContactGroup::Ref commonList; CContactGroup::Ref authWaitList; // account void OnAccountChanged(int prop); char *login; char *password; bool rememberPassword; bool RequestPassword(PasswordRequestBoxParam ¶m); bool ChangePassword(PasswordChangeBoxParam ¶m); HANDLE signin_lock; bool SignIn(int status); void __cdecl SignInAsync(void*); static wchar_t* LogoutReasons[]; static wchar_t* ValidationReasons[]; static wchar_t* PasswordChangeReasons[]; static LanguagesListEntry languages[223]; // messages void OnMessage(CConversation::Ref conversation, CMessage::Ref message); void OnMessageSended(CConversation::Ref conversation, CMessage::Ref message); void OnMessageReceived(CConversation::Ref conversation, CMessage::Ref message); // chat static char* Groups[]; bool IsChatRoom(HANDLE hContact); HANDLE GetChatRoomByID(const char *cid); HANDLE AddChatRoomByID(const char* cid, const char* name, DWORD flags = 0); char *CSkypeProto::GetChatUsers(const char *cid); void ChatValidateContact(HANDLE hItem, HWND hwndList, const char *contacts); void ChatPrepare(HANDLE hItem, HWND hwndList, const char *contacts); void GetInviteContacts(HANDLE hItem, HWND hwndList, SEStringList &invitedContacts); void InitChat(); char *StartChat(const char *cid, const SEStringList &invitedContacts); void JoinToChat(const char *cid, bool showWindow = true); void LeaveChat(const char *cid); void RaiseChatEvent(const char *cid, const char *sid, int evt, const DWORD itemData = 0, const char *status = NULL, const char *message = NULL); void SendChatMessage(const char *cid, const char *sid, const char *message); void AddChatContact(const char *cid, const char *sid, const char *group, const WORD status = ID_STATUS_ONLINE); void KickChatContact(const char *cid, const char *sid); void RemoveChatContact(const char *cid, const char *sid); INT_PTR __cdecl OnJoinChat(WPARAM wParam, LPARAM); INT_PTR __cdecl OnLeaveChat(WPARAM wParam, LPARAM); int __cdecl OnGCMenuHook(WPARAM, LPARAM lParam); int __cdecl OnGCEventHook(WPARAM, LPARAM lParam); // contacts void UpdateContactAuthState(HANDLE hContact, CContact::Ref contact); void UpdateContactAvatar(HANDLE hContact, CContact::Ref contact); void UpdateContactStatus(HANDLE hContact, CContact::Ref contact); void UpdateContactOnlineSinceTime(SEObject *obj, HANDLE hContact); void UpdateContactLastEventDate(SEObject *obj, HANDLE hContact); void OnSearchCompleted(HANDLE hSearch); void OnContactFinded(HANDLE hSearch, CContact::Ref contact); void OnContactChanged(CContact::Ref contact, int prop); void OnContactListChanged(const ContactRef& contact); bool IsProtoContact(HANDLE hContact); HANDLE GetContactBySid(const char* sid); HANDLE GetContactFromAuthEvent(HANDLE hEvent); HANDLE AddContactBySid(const char* sid, const char* nick, DWORD flags = 0); void SetAllContactStatus(int status); void __cdecl LoadContactList(void*); void __cdecl SearchBySidAsync(void*); void __cdecl SearchByNamesAsync(void*); void __cdecl SearchByEmailAsync(void*); // profile void UpdateProfileAvatar(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileAboutText(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileBirthday(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileCity(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileCountry(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileEmails(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileFullName(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileGender(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileHomepage(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileLanguages(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileMobilePhone(SEObject *obj, HANDLE hContact = NULL); void UpdateProfilePhone(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileOfficePhone(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileState(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileStatusMessage(SEObject *obj, HANDLE hContact = NULL); void UpdateProfileTimezone(SEObject *obj, HANDLE hContact = NULL); void UpdateProfile(SEObject *obj, HANDLE hContact = NULL); void __cdecl LoadOwnInfo(void*); // utils static void FakeAsync(void*); void InitCustomFolders(); static int DetectAvatarFormatBuffer(const char *pBuffer); static int DetectAvatarFormat(const wchar_t *path); wchar_t* GetContactAvatarFilePath(HANDLE hContact); int SkypeToMirandaLoginError(CAccount::LOGOUTREASON logoutReason); static void ShowNotification(const wchar_t *message, int flags = 0, HANDLE hContact = NULL); static void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, HANDLE hContact = NULL); static char *RemoveHtml(char *data); int SkypeToMirandaStatus(CContact::AVAILABILITY availability); CContact::AVAILABILITY MirandaToSkypeStatus(int status); // runtime void InitSkype(); void UninitSkype(); // instances static LIST instanceList; static int CompareProtos(const CSkypeProto *p1, const CSkypeProto *p2); void CreateService(const char* szService, SkypeServiceFunc serviceProc); void CreateServiceParam(const char* szService, SkypeServiceFunc serviceProc, LPARAM lParam); HANDLE CreateEvent(const char* szService); void HookEvent(const char*, SkypeEventFunc); int SendBroadcast(int type, int result, HANDLE hProcess, LPARAM lParam); int SendBroadcast(HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam); DWORD SendBroadcastAsync(HANDLE hContact, int type, int hResult, HANDLE hProcess, LPARAM lParam, size_t paramSize = 0); void ForkThread(SkypeThreadFunc, void*); HANDLE ForkThreadEx(SkypeThreadFunc, void*, UINT* threadID = NULL); // netlib HANDLE hNetLibUser; void InitNetLib(); void UninitNetLib(); void InitProxy(); void Log(const wchar_t *fmt, ...); // services static LIST serviceList; INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM); INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM); INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM); INT_PTR __cdecl SetMyAvatar(WPARAM, LPARAM); // icons static _tag_iconList IconList[]; // menu HGENMENU m_hMenuRoot; static HANDLE hChooserMenu; static HANDLE hPrebuildMenuHook; static HANDLE g_hContactMenuItems[CMITEMS_COUNT]; static HANDLE g_hContactMenuSvc[CMITEMS_COUNT]; static INT_PTR MenuChooseService(WPARAM wParam, LPARAM lParam); int OnPrebuildContactMenu(WPARAM wParam, LPARAM); // database HANDLE AddDataBaseEvent(HANDLE hContact, WORD type, DWORD time, DWORD flags, DWORD cbBlob, PBYTE pBlob); void RaiseMessageReceivedEvent( DWORD timestamp, const char* sid, const char* nick, const char* message = ""); void RaiseMessageSendedEvent( DWORD timestamp, const char* sid, const char* nick, const char* message = ""); void RaiseAuthRequestEvent( DWORD timestamp, const char* sid, const char* nick, const char* firstName = "", const char* lastName = "", const char* reason = ""); // database settings BYTE GetSettingByte(const char *setting, BYTE errorValue = 0); BYTE GetSettingByte(HANDLE hContact, const char *setting, BYTE errorValue = 0); WORD GetSettingWord(const char *setting, WORD errorValue = 0); WORD GetSettingWord(HANDLE hContact, const char *setting, WORD errorValue = 0); DWORD GetSettingDword(const char *setting, DWORD defVal = 0); DWORD GetSettingDword(HANDLE hContact, const char *setting, DWORD errorValue = 0); wchar_t *GetSettingString(const char *setting, wchar_t* errorValue = NULL); wchar_t *GetSettingString(HANDLE hContact, const char *setting, wchar_t* errorValue = NULL); char *GetDecodeSettingString(HANDLE hContact, const char *setting, char* errorValue = NULL); // bool SetSettingByte(const char *setting, BYTE value); bool SetSettingByte(HANDLE hContact, const char *setting, BYTE value); bool SetSettingWord(const char *setting, WORD value); bool SetSettingWord(HANDLE hContact, const char *setting, WORD value); bool SetSettingDword(const char *setting, DWORD value); bool SetSettingDword(HANDLE hContact, const char *setting, DWORD value); bool SetSettingString(const char *setting, const wchar_t* value); bool SetSettingString(HANDLE hContact, const char *setting, const wchar_t* value); bool SetDecodeSettingString(HANDLE hContact, const char *setting, const char* value); // void DeleteSetting(const char *setting); void DeleteSetting(HANDLE hContact, const char *setting); // dialog procs static INT_PTR CALLBACK SkypeMainOptionsProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); static INT_PTR CALLBACK SkypePasswordRequestProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK SkypePasswordChangeProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK SkypeDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK OwnSkypeDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK InviteToChatProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); };