1// 2// This file is part of the aMule Project. 3// 4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 5// Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net ) 6// 7// Any parts of this program derived from the xMule, lMule or eMule project, 8// or contributed by third-party developers are copyrighted by their 9// respective authors. 10// 11// This program is free software; you can redistribute it and/or modify 12// it under the terms of the GNU General Public License as published by 13// the Free Software Foundation; either version 2 of the License, or 14// (at your option) any later version. 15// 16// This program is distributed in the hope that it will be useful, 17// but WITHOUT ANY WARRANTY; without even the implied warranty of 18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19// GNU General Public License for more details. 20// 21// You should have received a copy of the GNU General Public License 22// along with this program; if not, write to the Free Software 23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 24// 25 26#include "CaptchaGenerator.h" 27#include "RandomFunctions.h" 28#include "MemFile.h" 29#include <wx/bitmap.h> 30#include <wx/dcmemory.h> 31#include <wx/font.h> 32 33 34#define LETTERSIZE 32 35#define CROWDEDSIZE 20 36 37// fairly simply captcha generator, might be improved is spammers think its really worth it solving captchas on aMule 38 39CCaptchaGenerator::CCaptchaGenerator(uint32 nLetterCount) 40{ 41 ReGenerateCaptcha(nLetterCount); 42} 43 44void CCaptchaGenerator::ReGenerateCaptcha(uint32 nLetterCount) 45{ 46 static wxString schCaptchaContent = wxT("ABCDEFGHJKLMNPQRSTUVWXYZ123456789"); 47 m_strCaptchaText.Clear(); 48 // Bitmap must be created with full depth, or it will fail on GTK 49 wxBitmap pimgResult(LETTERSIZE + (nLetterCount-1)*CROWDEDSIZE, 36); 50 wxMemoryDC dc(pimgResult); 51 dc.SetBackground(*wxWHITE_BRUSH); 52 dc.Clear(); 53 dc.SetTextForeground(*wxBLACK); 54 dc.SetTextBackground(*wxWHITE); 55 double lastrotate = 15.0; 56 57 for (uint32 i = 0; i < nLetterCount; i++) { 58 wxString strLetter(schCaptchaContent[GetRandomUint16() % schCaptchaContent.length()]); 59 m_strCaptchaText += strLetter; 60 61 uint16 nRandomSize = 30 - GetRandomUint16() % 12; 62 wxFont font(nRandomSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD); 63 dc.SetFont(font); 64 uint16 nRandomOffset = 3 + GetRandomUint16() % 8; 65 uint16 maxRotate = 50 - nRandomSize; // rotate small letters more than large letters 66 double fRotate = (double)(maxRotate - (GetRandomUint16() % (maxRotate*2))); 67 // limit angle diff - it causes too much overlap since wx rotates at the corner 68 // (maybe I'll redo that with some coordinate transformation one day) 69 if (fRotate - lastrotate > 20) { 70 fRotate = lastrotate + 20; 71 } else if (fRotate - lastrotate < -20) { 72 fRotate = lastrotate - 20; 73 } 74 dc.DrawRotatedText(strLetter, nRandomOffset + i * CROWDEDSIZE, 0, fRotate); 75 } 76 m_pimgCaptcha = pimgResult.ConvertToImage(); 77 // wx always saves as 24 bpp except when it gets this WELL DOCUMENTED option... 78 m_pimgCaptcha.SetOption(wxIMAGE_OPTION_BMP_FORMAT, wxBMP_1BPP); 79 // m_pimgCaptcha.SaveFile(wxT("captcha.bmp"), wxBITMAP_TYPE_BMP); 80} 81 82bool CCaptchaGenerator::WriteCaptchaImage(wxMemoryOutputStream& file) 83{ 84 return m_pimgCaptcha.SaveFile(file, wxBITMAP_TYPE_BMP); 85} 86