// GamePlayerCtl.cpp : Implementation of the CGamePlayerCtrl ActiveX Control class. #include "stdafx.h" #include #include #include "GamePlayer.h" #include "GamePlayerCtl.h" #include "GamePlayerPpg.h" #include "net/http.h" extern int ReadHttp(void *ioBuf, int iNum, CHttpClient *client); #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif inline bool llfile_IsDirChar(char c) { return c == '/'; } bool llfile_IsBackName( char *Path) { if( 0 == strncmp(Path, "../", 3) ) return true; return false; } char * llfile_SimplifyPath(const char *Path) { static char Simp[256]; Simp[0] = 0; int iCur = 0; int PathLen = strlen(Path); while(true) { int iLast = iCur; while(iCur < PathLen && !llfile_IsDirChar(Path[iCur])) iCur++; char Frac[256]; strcpy(Frac, &Path[iLast]); Frac[iCur-iLast] = 0; if(iCur == PathLen ) { strcat(Simp,Frac); break; } iCur++; if( Frac[0] == 0x00 && iCur != 1 ) //an erster Stelle erlaubt "/" continue; if( 0 == strcmp(Frac,".") ) continue; if( 0 == strcmp( Frac, ".." ) ) { int iBack = strlen(Simp) - 1; if(iBack >= 0) { while(iBack > 0 && !llfile_IsDirChar(Simp[iBack - 1])) iBack--; char Tail[256]; strcpy(Tail, &Simp[iBack] ); if(!llfile_IsBackName(Tail) ) { Simp[ iBack ] = 0; continue; } } } strcat(Simp,Frac); strcat(Simp,"/"); } return Simp; } IMPLEMENT_DYNCREATE(CGamePlayerCtrl, COleControl) ///////////////////////////////////////////////////////////////////////////// // Message map BEGIN_MESSAGE_MAP(CGamePlayerCtrl, COleControl) //{{AFX_MSG_MAP(CGamePlayerCtrl) ON_WM_LBUTTONDOWN() ON_WM_CREATE() //}}AFX_MSG_MAP ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Dispatch map BEGIN_DISPATCH_MAP(CGamePlayerCtrl, COleControl) //{{AFX_DISPATCH_MAP(CGamePlayerCtrl) // NOTE - ClassWizard will add and remove dispatch map entries // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_DISPATCH_MAP DISP_FUNCTION_ID(CGamePlayerCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE) END_DISPATCH_MAP() ///////////////////////////////////////////////////////////////////////////// // Event map BEGIN_EVENT_MAP(CGamePlayerCtrl, COleControl) //{{AFX_EVENT_MAP(CGamePlayerCtrl) // NOTE - ClassWizard will add and remove event map entries // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_EVENT_MAP END_EVENT_MAP() ///////////////////////////////////////////////////////////////////////////// // Property pages // TODO: Add more property pages as needed. Remember to increase the count! BEGIN_PROPPAGEIDS(CGamePlayerCtrl, 1) PROPPAGEID(CGamePlayerPropPage::guid) END_PROPPAGEIDS(CGamePlayerCtrl) ///////////////////////////////////////////////////////////////////////////// // Initialize class factory and guid IMPLEMENT_OLECREATE_EX(CGamePlayerCtrl, "GAMEPLAYER.GamePlayerCtrl.1", 0x10a2effa, 0xe76f, 0x40b0, 0x85, 0xb8, 0x16, 0x4d, 0x8f, 0x71, 0xd1, 0x1) ///////////////////////////////////////////////////////////////////////////// // Type library ID and version IMPLEMENT_OLETYPELIB(CGamePlayerCtrl, _tlid, _wVerMajor, _wVerMinor) ///////////////////////////////////////////////////////////////////////////// // Interface IDs const IID BASED_CODE IID_DGamePlayer = { 0x922c5410, 0x753d, 0x40fa, { 0xb6, 0xed, 0x84, 0x2a, 0xa1, 0x36, 0x7b, 0x2a } }; const IID BASED_CODE IID_DGamePlayerEvents = { 0xe1345616, 0xb292, 0x40cf, { 0xa9, 0xa2, 0xd8, 0xa3, 0x5a, 0x6, 0xb6, 0x12 } }; ///////////////////////////////////////////////////////////////////////////// // Control type information static const DWORD BASED_CODE _dwGamePlayerOleMisc = OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT | OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE; IMPLEMENT_OLECTLTYPE(CGamePlayerCtrl, IDS_GAMEPLAYER, _dwGamePlayerOleMisc) ///////////////////////////////////////////////////////////////////////////// // CGamePlayerCtrl::CGamePlayerCtrlFactory::UpdateRegistry - // Adds or removes system registry entries for CGamePlayerCtrl BOOL CGamePlayerCtrl::CGamePlayerCtrlFactory::UpdateRegistry(BOOL bRegister) { // TODO: Verify that your control follows apartment-model threading rules. // Refer to MFC TechNote 64 for more information. // If your control does not conform to the apartment-model rules, then // you must modify the code below, changing the 6th parameter from // afxRegApartmentThreading to 0. if (bRegister) return AfxOleRegisterControlClass( AfxGetInstanceHandle(), m_clsid, m_lpszProgID, IDS_GAMEPLAYER, IDB_GAMEPLAYER, afxRegApartmentThreading, _dwGamePlayerOleMisc, _tlid, _wVerMajor, _wVerMinor); else return AfxOleUnregisterClass(m_clsid, m_lpszProgID); } ///////////////////////////////////////////////////////////////////////////// // CGamePlayerCtrl::CGamePlayerCtrl - Constructor CGamePlayerCtrl::CGamePlayerCtrl() { InitializeIIDs(&IID_DGamePlayer, &IID_DGamePlayerEvents); // TODO: Initialize your control's instance data here. m_DllModul = 0; } ///////////////////////////////////////////////////////////////////////////// // CGamePlayerCtrl::~CGamePlayerCtrl - Destructor CGamePlayerCtrl::~CGamePlayerCtrl() { #ifdef XP_WIN //subclass it back if( m_DllModul) { PFStopGame *StopGame = (PFStopGame*) ::GetProcAddress(m_DllModul,"StopGame"); StopGame(m_hWnd); FreeLibrary(m_DllModul); } #endif } ///////////////////////////////////////////////////////////////////////////// // CGamePlayerCtrl::OnDraw - Drawing function void CGamePlayerCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); //pdc->Ellipse(rcBounds); pdc->SetTextColor( 0xff ); pdc->SetBkMode( TRANSPARENT ); CString cstr; cstr = _T("CGamePlayerCTRL SRC: "); cstr += m_Src; pdc->TextOut( 10, 20, cstr ); cstr = _T("Your page: "); cstr += m_CurrentUrl; pdc->TextOut( 10, 50, cstr ); cstr = _T("Servername: "); cstr += m_ServerName; pdc->TextOut( 10, 70, cstr ); cstr = _T("Path: "); cstr += m_Path; pdc->TextOut( 10, 90, cstr ); cstr = _T("Src: "); cstr += m_Src; pdc->TextOut( 10, 110, cstr ); cstr = _T("PageName: "); cstr += m_PageName; pdc->TextOut( 10, 130, cstr ); CRect rect; CBrush brh( 0xff0000 ); pdc->FrameRect( rcBounds, &brh ); } ///////////////////////////////////////////////////////////////////////////// // CGamePlayerCtrl::DoPropExchange - Persistence support void CGamePlayerCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); ////////////////////////////////////////////////////// //get all your params from / tag for IE PX_String( pPX, _T("src"), m_Src ); } ///////////////////////////////////////////////////////////////////////////// // CGamePlayerCtrl::OnResetState - Reset control to default state void CGamePlayerCtrl::OnResetState() { COleControl::OnResetState(); // Resets defaults found in DoPropExchange // TODO: Reset any other control state here. } ///////////////////////////////////////////////////////////////////////////// // CGamePlayerCtrl::AboutBox - Display an "About" box to the user void CGamePlayerCtrl::AboutBox() { CDialog dlgAbout(IDD_ABOUTBOX_GAMEPLAYER); dlgAbout.DoModal(); } ///////////////////////////////////////////////////////////////////////////// // CGamePlayerCtrl message handlers ////////////////////////////////////////////////////////////////////// //mozilla browser call this function to check whether or not there is a property //by name. bool CGamePlayerCtrl::MozHasMethod(NPIdentifier name) { return PR_FALSE; } //////////////////////////////////////////////////////////////////////////////////// //mozilla browser call this function the run a method that called by script //name: method name //args: parameters //argCount: parameter count //result: result will be returned to browser bool CGamePlayerCtrl::MozInvoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result) { return PR_FALSE; } //////////////////////////////////////////////////////////////////////////////////// //mozilla browser call this function to check whether or not there is a property bool CGamePlayerCtrl::MozHasProperty(NPIdentifier name) { return PR_FALSE; } ///////////////////////////////////////////////////////////////////////////////////// //browser script call this function to set a property value bool CGamePlayerCtrl::MozSetProperty(NPIdentifier name, const NPVariant *value) { return PR_TRUE; } /////////////////////////////////////////////////////////////////////////////////// //mozilla browser call this function to get a specified property value. bool CGamePlayerCtrl::MozGetProperty(NPIdentifier name, NPVariant *result) { return PR_TRUE; } ////////////////////////////////////////////////////////////////////////////////// //mozilla browser call this function to remove a property. bool CGamePlayerCtrl::MozRemoveProperty(NPIdentifier name) { return PR_FALSE; } void CGamePlayerCtrl::WindowResize(CRect &rect) { MoveWindow( rect ); } BOOL CGamePlayerCtrl::PreCreateWindow(CREATESTRUCT& cs) { cs.lpszClass = AfxRegisterWndClass( CS_VREDRAW | CS_HREDRAW ); return COleControl::PreCreateWindow(cs); } void CGamePlayerCtrl::OnLButtonDown(UINT nFlags, CPoint point) { MessageBox( _T("mouse LButtond is down."),_T("your plugin message handler"), MB_OK ); COleControl::OnLButtonDown(nFlags, point); } int CGamePlayerCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (COleControl::OnCreate(lpCreateStruct) == -1) return -1; IOleContainer* pContainer = NULL; IHTMLDocument2* pDoc = NULL; LPOLECLIENTSITE pClientSite = GetClientSite(); if( pClientSite ) pClientSite->GetContainer( &pContainer ); if ( pContainer != NULL ) { pContainer->QueryInterface( IID_IHTMLDocument2, (void **)&pDoc ); if( pDoc ) { BSTR url = NULL; pDoc->get_URL( &url ); if( url ) { _bstr_t burl( url,true ); m_CurrentUrl = (LPCTSTR)burl; SysFreeString( url ); SplitUrl(); DownLoadDLL(); // <<<<<<<<<<<Release(); } pContainer->Release(); } if( pClientSite ) pClientSite->Release(); return 0; } void CGamePlayerCtrl::SplitUrl() { m_CurrentUrl.Replace('\\','/'); if( strnicmp(m_CurrentUrl, "http://",7) == 0 ) { char buf[256]; strncpy(buf,m_CurrentUrl,256); char *SN = buf+7; char *A = strchr(SN,'/'); if( A ){ char sbuf[256]; memset(sbuf,0,sizeof(sbuf)); strncpy(sbuf,SN, A-SN); m_ServerName = sbuf; char * B = strrchr(A,'/'); if( B && B!= A ){ B++; // '/' Zeichen gehört dem pfad char sbuf[256]; memset(sbuf,0,sizeof(sbuf)); strncpy(sbuf,A, B-A); m_Path = sbuf; m_PageName = B; } else { //B==A... source file liegt im root m_Path = "/"; m_PageName = B+1; // } } } else { // Server domain holen, das ist nach http:// m_ServerName = ""; // file testen /************************************************************************/ /* file://C:\haha\haha\microsoft */ /* file:///C:\haha\haha\firefox */ /************************************************************************/ if( 0==strnicmp(m_CurrentUrl,"file://",7)){ char buf[256]; strncpy(buf,m_CurrentUrl,256); char * A = buf+7; if( *A == '/' && A[2] == ':' ) A++; { char * B = strrchr(A,'/'); if( B && B!= A ){ B++; // '/' Zeichen gehört dem pfad char sbuf[256]; memset(sbuf,0,sizeof(sbuf)); strncpy(sbuf,A, B-A); m_Path = sbuf; m_PageName = B; } else { //B==A... source file liegt im root m_Path = "/"; m_PageName = B+1; // } } } } // PATH + Src, dann simplyfy // test ob m_Src absolut ist, // wenn ja, dann path überschreiben if( m_Src.GetAt(0) == '/' ) { m_Path = m_Src; int pos = m_Path.ReverseFind('/'); if( pos > 0 ) m_Path.SetAt(pos,'\0'); } else { // Path um m_Src erweitern int pos = m_Src.ReverseFind('/'); if( pos ) m_Path += m_Src.Left(pos+1); } char buf[256]; strcpy(buf,m_Path); m_Path = llfile_SimplifyPath(buf); // m_Src verkürzen int pos = m_Src.ReverseFind('/'); if( pos ){ m_Src = m_Src.Mid(pos+1); } } BOOL CGamePlayerCtrl::DownLoadDLL() { if( m_ServerName.IsEmpty() == TRUE ) { // locales file char path[256]; strcpy(path,m_Path); strcat(path,m_Src); m_DllModul = LoadLibrary(path); } else { // Download vom Server CHttpClient * httpfile = new CHttpClient((char*)(const char*)m_ServerName,0,0); if( httpfile->GetLastError() == 0 ){ CString AbsPath = m_Path; AbsPath += m_Src; int rc = httpfile->Open((char*)(const char*)AbsPath); if( rc == 0 ) { int fsize = httpfile->GetFileSize(); char * BUF = (char*) malloc(fsize); int rc = ReadHttp(BUF,fsize,httpfile); if( rc != fsize ) { AfxMessageBox("Cannot find game data"); free(BUF); delete httpfile; return FALSE; } char tmpPath[256]; ::GetTempPath( 256, tmpPath); strcat(tmpPath,m_PageName); char * B = strrchr(tmpPath,'.'); if( B ){ strcpy(B,".gp32"); // andere kennung } try{ CStdioFile file(tmpPath,CFile::modeWrite|CFile::modeCreate|CFile::typeBinary); file.Write(BUF,fsize); file.Close(); } catch(CFileException *E) { AfxMessageBox("Saving cache file failed"); free(BUF); delete httpfile; return FALSE; } /************************************************************************/ /* FILE EXECUTE */ /************************************************************************/ m_DllModul = LoadLibrary(tmpPath); } else { AfxMessageBox("Loading Game failed"); delete httpfile; return FALSE; } } delete httpfile; } if( m_DllModul ){ CRect rect; GetClientRect(&rect); PFStartGame *StartGame = (PFStartGame*) ::GetProcAddress(m_DllModul,"StartGame"); if( StartGame ){ StartGame( m_hWnd, rect.right, rect.bottom, m_ServerName, m_Path, m_PageName, m_Src, m_Params); } } return TRUE; }