Subversion Repositories Games.Chess Giants

Rev

Rev 147 | Rev 164 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
// dialog_registration.cpp
2
 
3
#include "../common.h"
4
 
5
 
6
// dialog template
7
#define THIS_DIALOG DIALOG_REGISTER
8
 
9
 
83 pmbaty 10
// global variables used in this module only
11
static wchar_t candidate_email[128] = L"";
12
static unsigned __int32 candidate_code = 0; // 32 bits
13
 
14
 
14 pmbaty 15
// prototypes of local functions
16
static int CALLBACK DialogProc_ThisDialog (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam);
83 pmbaty 17
static unsigned __int32 RetrieveActivationCode (wchar_t *candidate_email, wchar_t **failure_reason);
14 pmbaty 18
 
19
 
20
void DialogBox_Registration (void)
21
{
22
   // helper function to fire up the modal dialog box
23
 
24
   // display the dialog box (set the parent to be the desktop)
25
   DialogBox (hAppInstance, MAKEINTRESOURCE (THIS_DIALOG), NULL, DialogProc_ThisDialog);
26
 
27
   return; // finished processing this dialog
28
}
29
 
30
 
31
static int CALLBACK DialogProc_ThisDialog (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam)
32
{
33
   // message handler for the dialog box
34
 
83 pmbaty 35
   static wchar_t temp_string[1024];
14 pmbaty 36
 
37
   unsigned short wParam_hiword;
38
   unsigned short wParam_loword;
83 pmbaty 39
   wchar_t *failure_reason;
40
   int write_index;
14 pmbaty 41
   int read_index;
42
   int length;
43
 
44
   // filter out the commonly used message values
45
   wParam_hiword = HIWORD (wParam);
46
   wParam_loword = LOWORD (wParam);
47
 
48
   // have we just fired up this window ?
49
   if (message == WM_INITDIALOG)
50
   {
51
      // center the window
52
      CenterWindow (hWnd, hMainWnd);
53
 
54
      // set dialog icons (small one for title bar & big one for task manager)
55
      SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon (hAppInstance, MAKEINTRESOURCE (ICON_MAIN)));
56
      SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) LoadIcon (hAppInstance, MAKEINTRESOURCE (ICON_MAIN)));
57
 
58
      // set window title and control texts
59
      SetWindowText (hWnd, LOCALIZE (L"Registration_Title"));
60
 
61
      // set the static texts
62
      Static_SetText (GetDlgItem (hWnd, STATICTEXT_REGISTRATION_QUESTION), LOCALIZE (L"Registration_Question"));
63
      Static_SetText (GetDlgItem (hWnd, STATICTEXT_REGISTRATION_INSTRUCTIONS), LOCALIZE (L"Registration_Instructions"));
153 pmbaty 64
      // set email address font
65
      SendMessage (GetDlgItem (hWnd, EDITBOX_REGISTRATION_EMAILADDRESS), WM_SETFONT, (WPARAM) GetStockObject (SYSTEM_FONT), 0);
83 pmbaty 66
      if (options.registration.user_email[0] != 0)
67
         SetDlgItemText (hWnd, EDITBOX_REGISTRATION_EMAILADDRESS, options.registration.user_email);
68
      else
147 pmbaty 69
         SetDlgItemText (hWnd, EDITBOX_REGISTRATION_EMAILADDRESS, LOCALIZE (L"Registration_YourEmailHere"));
14 pmbaty 70
      SetWindowText (GetDlgItem (hWnd, BUTTON_VALIDATECODE), LOCALIZE (L"Registration_ValidateCode"));
71
      Static_SetText (GetDlgItem (hWnd, STATICTEXT_REGISTRATION_STATUSBAR), LOCALIZE (L"Registration_StatusBar"));
72
 
73
      // set focus to the first settable item
74
      SendMessage (GetDlgItem (hWnd, EDITBOX_REGISTRATION_EMAILADDRESS), EM_SETSEL, 0, -1); // select all text
75
      SetFocus (GetDlgItem (hWnd, EDITBOX_REGISTRATION_EMAILADDRESS));
76
 
147 pmbaty 77
      // convert the Paypal bitmap and the status bar message to hyperlinks
78
      ConvertStaticToHyperlink (GetDlgItem (hWnd, BUTTON_DONATE));
14 pmbaty 79
      ConvertStaticToHyperlink (GetDlgItem (hWnd, STATICTEXT_REGISTRATION_STATUSBAR));
80
   }
81
 
82
   // else did we click the close button on the title bar ?
83
   else if (message == WM_CLOSE)
84
      EndDialog (hWnd, 0); // close the dialog box
85
 
86
   // else did we take action on one of the controls ?
87
   else if (message == WM_COMMAND)
88
   {
89
      // did we cancel the dialog box ? (IDCANCEL is a system-wide dialog box handler value, that catches the ESC key)
90
      if (wParam_loword == IDCANCEL)
91
         EndDialog (hWnd, 0); // close the dialog box
92
 
21 pmbaty 93
      // else did the user enter something in the edit boxes ?
94
      else if (wParam_hiword == EN_CHANGE)
95
      {
83 pmbaty 96
         // enable the validation button only if the PayPal email field has data
21 pmbaty 97
         GetDlgItemText (hWnd, EDITBOX_REGISTRATION_EMAILADDRESS, candidate_email, WCHAR_SIZEOF (candidate_email));
98
 
83 pmbaty 99
         // strip spaces and unprintable characters from candidate email, and bring it lowercase
14 pmbaty 100
         length = wcslen (candidate_email);
101
         write_index = 0;
102
         for (read_index = 0; read_index < length; read_index++)
19 pmbaty 103
            if (!iswspace (candidate_email[read_index]))
14 pmbaty 104
            {
83 pmbaty 105
               candidate_email[write_index] = tolower (candidate_email[read_index]); // force lowercase
106
               write_index++; // keep only valid signs and discard spaces
14 pmbaty 107
            }
108
         candidate_email[write_index] = 0; // ensure string is correctly terminated
109
 
147 pmbaty 110
         EnableWindow (GetDlgItem (hWnd, BUTTON_VALIDATECODE), ((candidate_email[0] != 0) && (wcslen (candidate_email) > 5) && (wcscmp (candidate_email, LOCALIZE (L"Registration_YourEmailHere")) != 0)
83 pmbaty 111
                                                                && (wcschr (candidate_email, L'@') != NULL) && (wcschr (candidate_email, L'.') != NULL)));
112
      }
14 pmbaty 113
 
83 pmbaty 114
      // else was it the validation button ?
115
      else if (wParam_loword == BUTTON_VALIDATECODE)
116
      {
117
         // query the remote server for the code associated with this email. If it fails, ask why.
118
         candidate_code = RetrieveActivationCode (candidate_email, &failure_reason);
14 pmbaty 119
 
83 pmbaty 120
         // was there a problem retrieving the code ?
121
         if ((failure_reason != NULL) && (failure_reason[0] != 0))
153 pmbaty 122
            MessageBox (hWnd, failure_reason, PROGRAM_NAME, MB_ICONERROR | MB_OK); // registration failed. Display an error and DON'T make the dialog box disappear
83 pmbaty 123
 
124
         // else is the retrieved data correct ?
14 pmbaty 125
         else if (IsRegistrationCorrect (candidate_email, candidate_code))
126
         {
83 pmbaty 127
            // if so, save activation email and activation code
128
            wcscpy_s (options.registration.user_email, WCHAR_SIZEOF (options.registration.user_email), candidate_email);
14 pmbaty 129
            options.registration.activation_code = candidate_code;
130
            MessageBox (hWnd, LOCALIZE (L"Registration_ThankYou"), PROGRAM_NAME, MB_ICONINFORMATION | MB_OK);
153 pmbaty 131
            EndDialog (hWnd, 0); // then display a thank you dialog box and make the dialog box disappear
14 pmbaty 132
         }
133
 
134
         // else the supplied data is wrong
135
         else
136
         {
83 pmbaty 137
            swprintf_s (temp_string, WCHAR_SIZEOF (temp_string), LOCALIZE (L"Registration_Error"), AUTHOR_EMAIL);
153 pmbaty 138
            MessageBox (hWnd, temp_string, PROGRAM_NAME, MB_ICONERROR | MB_OK); // wrong activation. Display an error and DON'T make the dialog box disappear
14 pmbaty 139
         }
140
      }
141
 
142
      // else was it the PayPal button ?
143
      else if (wParam_loword == BUTTON_DONATE)
89 pmbaty 144
      {
153 pmbaty 145
         MessageBox (hWnd, LOCALIZE (L"Registration_DontForget"), PROGRAM_NAME, MB_ICONWARNING | MB_OK); // users need to be reminded that they MUST write their email in the activation form
146
 
89 pmbaty 147
         if (wcscmp (languages[language_id].name, L"French") == 0)
148
            ShellExecute (NULL, L"open", PAYPAL_URL_FR, NULL, NULL, SW_MAXIMIZE); // open PayPal in French in the default browser, maximized
149
         else
150
            ShellExecute (NULL, L"open", PAYPAL_URL_XX, NULL, NULL, SW_MAXIMIZE); // open PayPal in English (default) the default browser, maximized
151
      }
14 pmbaty 152
 
153
      // else was it the status bar hyperlink ?
154
      else if (wParam_loword == STATICTEXT_REGISTRATION_STATUSBAR)
23 pmbaty 155
         ShellExecute (NULL, L"open", PROGRAM_URL, NULL, NULL, SW_MAXIMIZE); // open the main page in the default browser, maximized
14 pmbaty 156
   }
157
 
158
   // call the default dialog message processing function to keep things going
159
   return (false);
160
}
83 pmbaty 161
 
162
 
163
static unsigned __int32 RetrieveActivationCode (wchar_t *candidate_email, wchar_t **failure_reason)
164
{
165
   // this function queries the remote server for registration status. If OK, the received code is returned.
166
   // On error, 0 is returned and error_string points to the cause of the error (as reported by the server)
167
   // which is stored in a static buffer in this very function.
168
 
169
   static char http_buffer[1024]; // used both for request and reply
170
   static char ascii_email[128];
171
 
172
   struct sockaddr_in service;
173
   struct hostent *hostinfo;
174
   char *data_start;
175
   int write_index;
176
   int read_index;
177
   int length;
178
   SOCKET s;
179
 
153 pmbaty 180
   // initialize the network subsystem if required
181
   if (!Network_Init ())
83 pmbaty 182
   {
183
      *failure_reason = LOCALIZE (L"Registration_NetworkFailure");
184
      return (0); // couldn't initialize WinSock, return an error condition
185
   }
186
 
187
   // get our distribution server's IP address from the host name
188
   hostinfo = gethostbyname ("pmbaty.com");
189
   if (hostinfo == NULL)
190
   {
191
      *failure_reason = LOCALIZE (L"Registration_NetworkFailure");
192
      return (0); // couldn't resolve hostname, return an error condition
193
   }
194
 
195
   // fill in the sockaddr server structure with the server hostinfo data
196
   service.sin_family = AF_INET;
197
   service.sin_addr.s_addr = inet_addr (inet_ntoa (*(struct in_addr *) hostinfo->h_addr_list[0]));
198
   service.sin_port = htons (80); // connect to webserver there (port 80)
199
 
200
   // create our socket
201
   if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
202
   {
203
      *failure_reason = LOCALIZE (L"Registration_NetworkFailure");
204
      return (0); // couldn't create socket, return an error condition
205
   }
206
 
207
   // connect to the distributor's webserver using that socket
208
   if (connect (s, (struct sockaddr *) &service, sizeof (service)) == -1)
209
   {
210
      *failure_reason = LOCALIZE (L"Registration_NetworkFailure");
211
      return (0); // unable to connect to webserver, return an error condition
212
   }
213
 
214
   // build the HTTP query and send it
215
   ConvertTo7BitASCII (ascii_email, sizeof (ascii_email), candidate_email);
216
   sprintf_s (http_buffer, sizeof (http_buffer),
217
      "GET /chess/whatsmycode.php?email=%s HTTP/1.1\r\n"
218
      "Host: pmbaty.com\r\n"
219
      "Connection: close\r\n"
220
      "\r\n", ascii_email);
221
   length = strlen (http_buffer);
222
   write_index = send (s, http_buffer, length, 0); // send the HTTP query
223
   if (write_index != length)
224
   {
225
      *failure_reason = LOCALIZE (L"Registration_NetworkFailure");
226
      return (0); // unable to send HTTP query, return an error condition
227
   }
228
 
88 pmbaty 229
   // read the reply (10 seconds timeout)
230
   http_buffer[0] = 0;
153 pmbaty 231
   read_index = RecvWithTimeout (s, 10.0f, http_buffer, sizeof (http_buffer), 0);
83 pmbaty 232
   if (read_index < 1)
233
   {
234
      *failure_reason = LOCALIZE (L"Registration_NetworkFailure");
235
      return (0); // empty or erroneous HTTP reply, return an error condition
236
   }
237
 
238
   closesocket (s); // finished communicating, close TCP socket
239
 
240
   // terminate recv buffer and see where the useful data starts
241
   http_buffer[read_index] = 0;
242
   //MessageBoxA (NULL, http_buffer, "HTTP response", MB_OK);
243
   if ((data_start = strstr (http_buffer, "Success=")) != NULL)
244
   {
245
      *failure_reason = L""; // no error, set an empty string as the failure reason
246
      return ((unsigned __int32) atoll (&data_start[strlen ("Success=")])); // and return the candidate code we got
247
   }
248
   else if ((data_start = strstr (http_buffer, "Error=")) != NULL)
249
   {
250
      data_start += strlen ("Error=");
251
      if (strchr (data_start, '\r') != NULL) *strchr (data_start, '\r') = 0;
252
      if (strchr (data_start, '\n') != NULL) *strchr (data_start, '\n') = 0;
253
      if      (_stricmp (data_start, "WrongEmail") == 0)         *failure_reason = LOCALIZE (L"Registration_WrongEmail");
254
      else if (_stricmp (data_start, "UnknownEmail") == 0)       *failure_reason = LOCALIZE (L"Registration_UnknownEmail");
255
      else if (_stricmp (data_start, "TooManyActivations") == 0) *failure_reason = LOCALIZE (L"Registration_TooManyActivations");;
88 pmbaty 256
      return (0); // server returned an error, return an error condition
83 pmbaty 257
   }
258
 
88 pmbaty 259
   *failure_reason = LOCALIZE (L"Registration_NetworkFailure"); // this should never happen
83 pmbaty 260
   return (0); // server returned an error, return an error condition
261
}