1 // nel_launcherDlg.cpp : implementation file
5 #include "nel_launcher.h"
6 #include "nel_launcherDlg.h"
13 #include "nel/misc/config_file.h"
14 #include "nel/misc/path.h"
19 using namespace NLMISC
;
21 CConfigFile ConfigFile
;
26 static char THIS_FILE[] = __FILE__;
29 const char *PleaseWaitFilename
= "pleasewait.html";
31 void CNel_launcherDlg::openUrl (const std::string
&url
)
33 m_explore
.Navigate(url
.c_str(), NULL
, NULL
, NULL
, NULL
);
36 /////////////////////////////////////////////////////////////////////////////
37 // CNel_launcherDlg dialog
39 CNel_launcherDlg::CNel_launcherDlg(CWnd
* pParent
/*=NULL*/)
40 : CDialog(CNel_launcherDlg::IDD
, pParent
)
42 //{{AFX_DATA_INIT(CNel_launcherDlg)
43 // NOTE: the ClassWizard will add member initialization here
45 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
46 m_hIcon
= AfxGetApp()->LoadIcon(IDR_MAINFRAME
);
49 void CNel_launcherDlg::DoDataExchange(CDataExchange
* pDX
)
51 CDialog::DoDataExchange(pDX
);
52 //{{AFX_DATA_MAP(CNel_launcherDlg)
53 DDX_Control(pDX
, IDC_EXPLORER1
, m_explore
);
57 BEGIN_MESSAGE_MAP(CNel_launcherDlg
, CDialog
)
58 //{{AFX_MSG_MAP(CNel_launcherDlg)
66 /////////////////////////////////////////////////////////////////////////////
67 // CNel_launcherDlg message handlers
69 BOOL
CNel_launcherDlg::OnInitDialog()
71 NLMISC::CApplicationContext ApplicationContext
;
73 CDialog::OnInitDialog();
75 // Set the icon for this dialog. The framework does this automatically
76 // when the application's main window is not a dialog
77 SetIcon(m_hIcon
, TRUE
); // Set big icon
78 SetIcon(m_hIcon
, FALSE
); // Set small icon
80 //CWebBrowser2 m_browser - member variable
85 ConfigFile
.load ("nel_launcher.cfg");
87 // get the working path
88 string workingPath
= CPath::getFullPath (ConfigFile
.getVar ("Application").asString(2));
90 if (!NLMISC::CFile::isExists (workingPath
))
92 nlerror ("Working path '%s' doesn't exists", workingPath
.c_str ());
95 // load the pleasewait html page if available in the nel_launcher directory
96 bool PleaseWaitLoaded
= false;
97 string PleaseWaitFullPath
;
98 PleaseWaitFullPath
= CPath::getFullPath (PleaseWaitFilename
, false);
99 if (NLMISC::CFile::isExists (PleaseWaitFullPath
))
101 openUrl(PleaseWaitFullPath
.c_str());
102 PleaseWaitLoaded
= true;
105 _chdir (workingPath
.c_str ());
107 // load the pleasewait html page if available in the client directory
108 PleaseWaitFullPath
= CPath::getFullPath (PleaseWaitFilename
, false);
109 if (!PleaseWaitLoaded
&& NLMISC::CFile::isExists (PleaseWaitFullPath
))
111 openUrl(PleaseWaitFullPath
.c_str());
115 if (NLMISC::CFile::fileExists ("update_nel_launcher.bat"))
116 NLMISC::CFile::deleteFile ("update_nel_launcher.bat");
118 string Version
= getVersion ();
120 string url
= "http://"+ConfigFile
.getVar ("StartupHost").asString()+ConfigFile
.getVar ("StartupPage").asString();
121 url
+= "?newClientVersion=" + Version
;
122 url
+= "&newClientApplication=" + ConfigFile
.getVar ("Application").asString(0);
126 return TRUE
; // return TRUE unless you set the focus to a control
129 // If you add a minimize button to your dialog, you will need the code below
130 // to draw the icon. For MFC applications using the document/view model,
131 // this is automatically done for you by the framework.
133 void CNel_launcherDlg::OnPaint()
137 CPaintDC
dc(this); // device context for painting
139 SendMessage(WM_ICONERASEBKGND
, (WPARAM
) dc
.GetSafeHdc(), 0);
141 // Center icon in client rectangle
142 int cxIcon
= GetSystemMetrics(SM_CXICON
);
143 int cyIcon
= GetSystemMetrics(SM_CYICON
);
145 GetClientRect(&rect
);
146 int x
= (rect
.Width() - cxIcon
+ 1) / 2;
147 int y
= (rect
.Height() - cyIcon
+ 1) / 2;
150 dc
.DrawIcon(x
, y
, m_hIcon
);
158 // The system calls this to obtain the cursor to display while the user drags
159 // the minimized window.
160 HCURSOR
CNel_launcherDlg::OnQueryDragIcon()
162 return (HCURSOR
) m_hIcon
;
165 BEGIN_EVENTSINK_MAP(CNel_launcherDlg
, CDialog
)
166 //{{AFX_EVENTSINK_MAP(CNel_launcherDlg)
167 ON_EVENT(CNel_launcherDlg
, IDC_EXPLORER1
, 250 /* BeforeNavigate2 */, OnBeforeNavigate2Explorer1
, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL
)
168 ON_EVENT(CNel_launcherDlg
, IDC_EXPLORER1
, 259 /* DocumentComplete */, OnDocumentCompleteExplorer1
, VTS_DISPATCH VTS_PVARIANT
)
169 //}}AFX_EVENTSINK_MAP
172 void CNel_launcherDlg::OnBeforeNavigate2Explorer1(LPDISPATCH pDisp
, VARIANT FAR
* URL
, VARIANT FAR
* Flags
, VARIANT FAR
* TargetFrameName
, VARIANT FAR
* PostData
, VARIANT FAR
* Headers
, BOOL FAR
* Cancel
)
174 // set the user agent to nel_launcher changing the header
175 CString
strHeader(Headers
->bstrVal
);
178 IWebBrowser2
*pBrowser
;
181 pDisp
->QueryInterface(IID_IWebBrowser2
, (void**) &pBrowser
);
182 pBrowser
->get_Container(&pWebDisp
);
184 BSTR bstr
= SysAllocString(L
"User-Agent: nel_launcher\r\n");
185 Headers
->bstrVal
= bstr
;
187 pBrowser
->Navigate2(URL
, Flags
, TargetFrameName
, PostData
, Headers
);
197 SysFreeString (bstr
);
203 /* CString cstr = URL->bstrVal;
204 string str = string((const char*)cstr);
206 if (str.find ("clientVersion=") == string::npos)
210 FILE *fp = fopen ("VERSION", "rb");
214 if (fgets (ver, 1000, fp) != NULL)
223 if (url.find ("?") != string::npos)
231 // url += "clientVersion=" + Version;
232 // url += "&clientApplication=" + ConfigFile.getVar ("Application").asString(0);
235 m_explore.Navigate(url.c_str(), Flags, TargetFrameName, PostData, Headers);
241 vector<unsigned short> v;
242 for (uint i = 0; i < url.size (); i++)
243 v.push_back ((unsigned short)url[i]);
245 BSTR bstr = SysAllocString((const unsigned short *)&(v[0]));
248 OnBeforeNavigate2Explorer1(pDisp, &vurl, Flags, TargetFrameName, PostData, Headers, Cancel);
250 SysFreeString (bstr);
258 /* if (str.find("?nel_quit=1") != string::npos)
263 string token ("nel_exe=");
265 int spos = str.find (token);
266 if (spos == string::npos) return;
268 int spos2 = str.find ("&", spos+token.size ()+1);
269 if (spos == string::npos) return;
272 string exe = str.substr (spos+token.size (), spos2-spos-token.size ());
274 CConfigFile::CVar *var = ConfigFile.getVarPtr (exe);
278 smprintf (str, 1024, "Don't know the executable filename for the application '%s'", exe.c_str ());
279 MessageBox (str, "nel_launcher error");
284 exe = var->asString (0);
285 path = var->asString (1);
289 spos = str.find (token);
290 if (spos == string::npos) return;
292 string rawargs = str.substr (spos+token.size ());
294 // decode arguments (%20 -> space)
296 vector<string> vargs;
297 const char *args[50];
300 int pos1 = 0, pos2 = 0;
303 pos2 = rawargs.find("%20", pos1);
304 if (pos2==string::npos)
306 if(pos1!=rawargs.size())
308 string res = rawargs.substr (pos1);
309 vargs.push_back (res);
315 string res = rawargs.substr (pos1, pos2-pos1);
316 vargs.push_back (res);
323 if(vargs.size()>47) size = 47;
324 else size = vargs.size();
326 args[0] = exe.c_str ();
327 for(i = 0; i < size; i++)
329 args[i+1] = vargs[i].c_str ();
334 // execute, should better use CreateProcess()
336 _chdir (path.c_str());
337 _execvp (exe.c_str(), args);
345 int pos = cmd.find ("%20");
346 if (pos == string::npos)
349 cmd.replace (pos, 3, " ");
352 WinExec (cmd.c_str(), SW_SHOWNORMAL);
356 void CNel_launcherDlg::OnSize(UINT nType
, int cx
, int cy
)
358 CDialog::OnSize(nType
, cx
, cy
);
360 if (m_explore
.m_hWnd
== NULL
) return;
362 GetClientRect (&rect
);
363 m_explore
.SetWindowPos ((CWnd
* )HWND_TOP
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, SWP_SHOWWINDOW
);
366 string
getValue (const string
&str
, const string
&token
)
368 string realtoken
= token
+"=\"";
369 uint spos
= str
.find (realtoken
);
370 if (spos
== string::npos
) return "";
372 uint spos2
= str
.find ("\"", spos
+realtoken
.size ());
373 if (spos
== string::npos
) return "";
375 return str
.substr (spos
+realtoken
.size (), spos2
-spos
-realtoken
.size ());
379 void CNel_launcherDlg::launch (const string
&str
)
381 string exe
= ConfigFile
.getVar ("Application").asString(1);
384 if (ConfigFile
.getVar ("Application").size() == 4)
385 path
= ConfigFile
.getVar ("Application").asString(3);
387 string rawargs
= getValue (str
, "nelArgs");
389 nlinfo ("extracting string '%s'", str
.c_str ());
391 // convert the command line in an array of string for the _execvp() function
393 vector
<string
> vargs
;
394 const char *args
[50];
397 uint pos1
= 0, pos2
= 0;
400 pos2
= rawargs
.find(" ", pos1
);
401 if (pos2
==string::npos
)
403 if(pos1
!=rawargs
.size())
405 string res
= rawargs
.substr (pos1
);
406 vargs
.push_back (res
);
412 string res
= rawargs
.substr (pos1
, pos2
-pos1
);
413 vargs
.push_back (res
);
420 if(vargs
.size()>47) size
= 47;
421 else size
= vargs
.size();
423 args
[0] = exe
.c_str ();
424 for(i
= 0; i
< size
; i
++)
426 args
[i
+1] = vargs
[i
].c_str ();
430 // go in the good path before launching
432 _chdir (path
.c_str ());
434 // execute, should better use CreateProcess()
435 if (_execvp (exe
.c_str(), args
) == -1)
437 // error occurs during the launch
438 string str
= toString("Can't execute '%s': code=%d %s", exe
.c_str(), errno
, strerror(errno
));
439 MessageBox (str
.c_str(), "Error");
444 void CNel_launcherDlg::patch (const string
&str
)
446 string url
= "http://"+ConfigFile
.getVar ("StartupHost").asString();
448 string serverVersion
= getValue (str
, "serverVersion");
451 urlok
+= getValue (str
, "nelUrl");
452 urlok
+= "&newClientVersion=";
453 urlok
+= serverVersion
;
455 string urlfailed
= url
;
456 urlfailed
+= getValue (str
, "nelUrlFailed");
457 urlfailed
+= "&reason=";
459 startPatchThread (getValue (str
, "nelServerPath"), serverVersion
, urlok
, urlfailed
, "<br>");
461 SetTimer(0,100,NULL
);
465 string serverVersion = getValue (str, "serverVersion");
466 patchVersion (getValue (str, "nelServerPath"), serverVersion);
468 // this url is where we have to go after patching success
469 url += getValue (str, "nelUrl");
470 url += "&newClientVersion=";
471 url += serverVersion;
475 nlwarning ("Patching failed '%s'", e.what());
477 url += getValue (str, "nelUrlFailed");
482 // go to the next url
483 openUrl (url.c_str());*/
486 void CNel_launcherDlg::OnTimer(UINT nIDEvent
)
489 if (patchState(state
, log
))
491 LPDISPATCH lpDispatch
;
492 lpDispatch
= m_explore
.GetDocument();
493 if (lpDispatch
== NULL
) return;
495 IHTMLDocument2
* pHTMLDocument2
;
497 hr
= lpDispatch
->QueryInterface(IID_IHTMLDocument2
, (LPVOID
*) &pHTMLDocument2
);
498 lpDispatch
->Release();
499 if (FAILED(hr
)) return;
500 if (pHTMLDocument2
== NULL
) return;
503 hr
= pHTMLDocument2
->get_body(&pBody
);
504 if (FAILED(hr
)) return;
505 if (pBody
== NULL
) return;
508 pBody
->get_innerHTML(&bstr
);
509 CString
csourceCode( bstr
);
510 string
htmlCode( (LPCSTR
)csourceCode
);
513 string tokenStart
= "<!--nel_start_state-->";
514 string tokenEnd
= "<!--nel_end_state-->";
516 int pos
= csourceCode
.Find (tokenStart
.c_str());
517 if (pos
== -1) return;
518 int pos2
= csourceCode
.Find (tokenEnd
.c_str());
519 if (pos2
== -1) return;
521 CString oldstate
= csourceCode
.Mid (pos
, pos2
-pos
);
523 if (csourceCode
.Replace (oldstate
, string(tokenStart
+state
).c_str ()) == 0)
526 string tokenStartLog
= "<!--nel_start_log-->";
527 string tokenEndLog
= "<!--nel_end_log-->";
529 int pos3
= csourceCode
.Find (tokenStartLog
.c_str());
530 if (pos3
== -1) return;
532 int pos4
= csourceCode
.Find (tokenEndLog
.c_str());
533 if (pos4
== -1) return;
535 CString oldlog
= csourceCode
.Mid (pos3
, pos4
-pos3
);
537 if (csourceCode
.Replace (oldlog
, string(tokenStartLog
+log
).c_str ()) == 0)
540 pBody
->put_innerHTML(csourceCode
.AllocSysString ()); //insert the html
547 if (patchEnded(url
, res
))
552 MessageBox ("Patch completed succesfuly.", "patch");
554 MessageBox ("Patch could not be completed due to an error.", "patch");
555 openUrl (url
.c_str());
560 void CNel_launcherDlg::OnDocumentCompleteExplorer1(LPDISPATCH pDisp
, VARIANT FAR
* URL
)
562 IHTMLDocument2
* pHTMLDocument2
;
563 LPDISPATCH lpDispatch
;
564 lpDispatch
= m_explore
.GetDocument();
569 hr
= lpDispatch
->QueryInterface(IID_IHTMLDocument2
, (LPVOID
*) &pHTMLDocument2
);
570 lpDispatch
->Release();
575 if (pHTMLDocument2
== NULL
)
579 hr
= pHTMLDocument2
->get_body(&pBody
);
588 pBody
->get_innerHTML(&bstr
);
589 CString
csourceCode( bstr
);
590 string
str( (LPCSTR
)csourceCode
);
596 // now I have the web page, look if there's something interesting in it.
598 // if something start with <!--nel it s cool
599 string action
= getValue (str
, "<!--nel");
604 string token
= "<!--nel";
605 uint spos
= str
.find (token
);
606 uint spos2
= str
.find ("-->", spos
+token
.size ()+1);
607 string comment
= str
.substr (spos
+token
.size (), spos2
-spos
-token
.size ());
609 if (action
=="launch")
611 else if (action
=="patch")