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.

423 lines
9.6 KiB
C++

#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include "mplugin.h"
#include "npupp.h"
#include "net/http.h"
typedef unsigned char TxU8;
static LRESULT CALLBACK PluginWinProc(HWND, UINT, WPARAM, LPARAM);
class ScriptablePluginObject : public NPObject
{
public:
ScriptablePluginObject(NPP npp)
{
m_MPlugin = NULL;
m_Npp = npp;
}
CMPlugin *m_MPlugin;
NPP m_Npp;
};
static NPObject *SPO_Allocate(NPP npp,NPClass *aClass)
{
return new ScriptablePluginObject(npp);
}
static void SPO_Deallocate(NPObject *obj)
{
delete (ScriptablePluginObject *)obj;
}
static void SPO_Invalidate(NPObject *obj)
{
}
/////////////////////////////////////////////////////////////////////////////////
//mozilla uses HasMethod, Invoke, SetProperty, GetProperty, HasProperty
//to qyery plugin for method and properties
static bool SPO_HasMethod(NPObject *obj, NPIdentifier name)
{
return ((CGamePlayerCtrl*)((ScriptablePluginObject*)obj)->m_MPlugin->m_Wnd)->MozHasMethod( name );
}
static bool SPO_Invoke(NPObject *obj, NPIdentifier name, const NPVariant *args,
uint32_t argCount, NPVariant *result)
{
return ((CGamePlayerCtrl*)((ScriptablePluginObject*)obj)->m_MPlugin->m_Wnd)->MozInvoke( name,args,argCount,result );
}
static bool SPO_SetProperty(NPObject *obj, NPIdentifier name, const NPVariant *value)
{
return ((CGamePlayerCtrl*)((ScriptablePluginObject*)obj)->m_MPlugin->m_Wnd)->MozSetProperty( name,value );
}
static bool SPO_HasProperty(NPObject * obj, NPIdentifier name)
{
return ((CGamePlayerCtrl*)((ScriptablePluginObject*)obj)->m_MPlugin->m_Wnd)->MozHasProperty( name );
}
static bool SPO_RemoveProperty(NPObject *obj, NPIdentifier name )
{
return ((CGamePlayerCtrl*)((ScriptablePluginObject*)obj)->m_MPlugin->m_Wnd)->MozRemoveProperty( name );
}
static bool SPO_GetProperty(NPObject *obj, NPIdentifier name, NPVariant *result)
{
return ((CGamePlayerCtrl*)((ScriptablePluginObject*)obj)->m_MPlugin->m_Wnd)->MozGetProperty( name,result );
}
static bool SPO_InvokeDefault( NPObject *npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result)
{
return FALSE;
}
NPClass sSPO_Class = {
NP_CLASS_STRUCT_VERSION,
SPO_Allocate,
SPO_Deallocate,
SPO_Invalidate,
SPO_HasMethod,
SPO_Invoke,
SPO_InvokeDefault,
SPO_HasProperty,
SPO_GetProperty,
SPO_SetProperty,
SPO_RemoveProperty
};
static NPIdentifier sFoo_id;
static NPIdentifier sBar_id;
static NPIdentifier sDocument_id;
static NPIdentifier sBody_id;
static NPIdentifier sCreateElement_id;
static NPIdentifier sCreateTextNode_id;
static NPIdentifier sAppendChild_id;
static NPObject *sWindowObj;
CMPlugin::CMPlugin(NPP pNPInstance) :
m_pNPInstance(pNPInstance),
m_IsPluginInitialized(FALSE),
m_pScriptableObject(NULL),
m_lpOldProc(NULL)
{
m_Wnd = NULL;
bec = 0;
}
CMPlugin::~CMPlugin()
{
if (m_pScriptableObject)
NPN_ReleaseObject(m_pScriptableObject);
// CLosePlugin() destruktor
}
int ReadHttp(void *ioBuf, int iNum, CHttpClient *client)
{
//char buf[256];
TxU8* target_buf = (TxU8*) ioBuf;
int readbytes = 0;
while( readbytes < iNum )
{
int read_now = 15000;
if( read_now + readbytes > iNum ){
read_now = iNum - readbytes;
}
int rc = client->ReadHttp((char*)target_buf,read_now);
if( rc != read_now ){
if( rc == -1 ) // -1
return readbytes;
else{
//weniger gelesen
read_now = rc; // im falle von ftp z.b.
}
}
target_buf += read_now;
readbytes += read_now;
//m_totalbytes += read_now;
//sprintf(buf,"%s\n%d", m_curFile, readbytes );
/* if(m_callback)
{
int rc = m_callback(m_curFile, m_totalbytes, m_totalfiles, (int)(((float)readbytes/iNum)*100.0f), m_userPtr );
if( rc != 0 )
return readbytes; // Abort
}
*/
}
return iNum;
}
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//actually, you can create your window by any method you want,
//then just subclass your window to the window created by browser
//get current page url here,
NPBool CMPlugin::InitPlugin(NPWindow* pNPWindow)
{
//following demostrate creating a registered class window.
bec = new CGamePlayerCtrl;
m_Wnd = bec;
NPIdentifier n = NPN_GetStringIdentifier("document");
NPVariant rval;
NPObject *doc;
NPN_GetValue(m_pNPInstance, NPNVWindowNPObject, &sWindowObj);
NPN_GetProperty(m_pNPInstance, sWindowObj, n, &rval);
if (NPVARIANT_IS_OBJECT(rval) && (doc = NPVARIANT_TO_OBJECT(rval)))
{
//please note, you can get domain or URL, it's up to you which one you want.
//NPIdentifier n = NPN_GetStringIdentifier("domain");
NPIdentifier n = NPN_GetStringIdentifier("URL");
bool a = NPN_HasProperty( m_pNPInstance, doc, n );
if( a )
{
NPN_GetProperty( m_pNPInstance, doc,n, &rval );
if( rval.type == NPVariantType_String &&
rval.value.stringValue.utf8characters &&
rval.value.stringValue.utf8length > 0 )
{
bec->m_CurrentUrl = rval.value.stringValue.utf8characters;
}
NPN_ReleaseVariantValue(&rval);
}
}
if( doc ) NPN_ReleaseObject(doc);
sWindowObj = NULL;
// test ob file system
// Https nicht zugelassen
bec->m_Src = m_Src;
bec->SplitUrl();
//
// //TODO add parameters you saved from page to your plugin
CRect rect;
rect.left = 0;
rect.top = 0;
rect.right = pNPWindow->width;
rect.bottom = pNPWindow->height;
CWnd *wnd = CWnd::FromHandle( (HWND)pNPWindow->window );
bec->Create( _T("winclass"), _T("GamePlayer"), WS_CHILD | WS_VISIBLE, rect,wnd , 11001);
//m_hWnd = (HWND)pNPWindow->window;
m_hWnd = bec->m_hWnd;
// subclass window so we can intercept window messages and
// do our drawing to it
m_lpOldProc = SubclassWindow( m_hWnd, (WNDPROC)PluginWinProc );
// associate window with our CMPlugin object so we can access
// it in the window procedure
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);
if( bec->m_ServerName.IsEmpty() == TRUE )
{
// locales file
char path[256];
strcpy(path,bec->m_Path);
strcat(path,bec->m_Src);
bec->m_DllModul = LoadLibrary(path);
}
else
{
// Download vom Server
/* CHttpClient * httpfile = new CHttpClient((char*)(const char*)bec->m_ServerName,0,0);
if( httpfile->GetLastError() == 0 ){
CString AbsPath = bec->m_Path;
AbsPath += bec->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("Loading Game from webserver failed");
free(BUF);
delete httpfile;
return FALSE;
}
char tmpPath[256];
::GetTempPath( 256, tmpPath);
strcat(tmpPath,bec->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");
AfxMessageBox(E->m_cause);
free(BUF);
delete httpfile;
return FALSE;
}
*/
char tmpPath[256];
::GetTempPath( 256, tmpPath);
strcat(tmpPath,bec->m_PageName);
char * B = strrchr(tmpPath,'.');
if( B ){
strcpy(B,".gp32"); // andere kennung
}
CString AbsPath = "http://";
AbsPath += bec->m_ServerName;
AbsPath += bec->m_Path;
AbsPath += bec->m_Src;
//AfxMessageBox(AbsPath);
if(URLDownloadToFile(0,AbsPath,tmpPath,0,0))
{
CString msg = "Error:\nFile Not Found or you are offline";
msg += "\n";
msg += AbsPath;
MessageBox(0,msg,"Error",MB_OK | MB_ICONERROR);
}
else
{
/************************************************************************/
/* FILE EXECUTE */
/************************************************************************/
bec->m_DllModul = LoadLibrary(tmpPath);
}
// }
// else
// {
// AfxMessageBox("Loading Game from webserver failed");
// //delete httpfile;
// return FALSE;
// }
}
//delete httpfile;
// }
if( bec->m_DllModul ){
PFStartGame *StartGame = (PFStartGame*) ::GetProcAddress(bec->m_DllModul,"StartGame");
if( StartGame ){
StartGame(
m_hWnd,
pNPWindow->width,
pNPWindow->height,
bec->m_ServerName,
bec->m_Path,
bec->m_PageName,
bec->m_Src,
bec->m_Params);
}
}
m_IsPluginInitialized = TRUE;
return TRUE;
}
void CMPlugin::ClosePlugin()
{
#ifdef XP_WIN
//subclass it back
if( m_lpOldProc) SubclassWindow( m_hWnd, m_lpOldProc);
m_hWnd = NULL;
#endif
if( m_Wnd )
{
delete m_Wnd;
}
m_IsPluginInitialized = FALSE;
}
int16 CMPlugin::handleEvent(void* event)
{
return 0;
}
NPObject *
CMPlugin::GetScriptableObject()
{
if (!m_pScriptableObject) {
m_pScriptableObject = NPN_CreateObject(m_pNPInstance, &sSPO_Class);
((ScriptablePluginObject*)m_pScriptableObject)->m_MPlugin = this;
}
if (m_pScriptableObject) {
NPN_RetainObject(m_pScriptableObject);
}
return m_pScriptableObject;
}
static LRESULT CALLBACK PluginWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if( msg == WM_SIZE )
{ //prcoess browser resize message
CMPlugin * p = (CMPlugin *)GetWindowLong(hWnd, GWL_USERDATA);
if( p )
{//resize plugin
CRect rect;
::GetWindowRect(hWnd,rect );
CPoint pt( rect.left, rect.top );
::ScreenToClient(hWnd,&pt );
rect.left = pt.x;
rect.top = pt.y;
pt.x = rect.right;
pt.y = rect.bottom;
::ScreenToClient(hWnd,&pt );
rect.right = pt.x;
rect.bottom = pt.y;
((CGamePlayerCtrl*)p->m_Wnd)->WindowResize( rect );
}
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}