You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

615 lines
14 KiB
C++

// GamePlayerCtl.cpp : Implementation of the CGamePlayerCtrl ActiveX Control class.
#include "stdafx.h"
#include <mshtml.h>
#include <comdef.h>
#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 <object>/<embed> 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(); // <<<<<<<<<<<<startgame mit MSIE
}
pDoc->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<65>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<65>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 <20>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<72>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;
}