| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "webConfig.h"
- #include "webCommon.h"
- #include <string>
- #include <vector>
- // Platform specific shared library handling
- #ifdef WIN32
- #pragma warning( disable : 4996)
- #define TORQUE_OPEN LoadLibraryA
- #define TORQUE_FUNCTION GetProcAddress
- #define TORQUE_CLOSE FreeLibrary
- #define strncasecmp strnicmp
- #define strcasecmp stricmp
- #else // Mac
- #define TORQUE_OPEN(path) dlopen(path, RTLD_LAZY | RTLD_LOCAL)
- #define TORQUE_FUNCTION dlsym
- #define TORQUE_CLOSE dlclose
- #endif
- // C Interface exported from the Torque 3D DLL (or Bundle on Mac)
- extern "C"
- {
- // initialize Torque 3D including argument handling
- bool (*torque_engineinit)(int argc, const char **argv) = NULL;
- // tick Torque 3D's main loop
- int (*torque_enginetick)() = NULL;
- // set Torque 3D into web deployment mode (disable fullscreen exlusive mode, etc)
- int (*torque_setwebdeployment)() = NULL;
- // shutdown the engine
- bool (*torque_engineshutdown)() = NULL;
- // signal an engine shutdown (as with the quit(); console command)
- void (*torque_enginesignalshutdown)() = NULL;
- // reset the engine, unloading any current level and returning to the main menu
- void (*torque_reset)() = NULL;
- // Evaluate arbitrary TorqueScript (ONLY CALL torque_evaluate FROM TRUSTED CODE!!!)
- const char* (*torque_evaluate)(const char* code) = NULL;
- // Get a console variable
- const char* (*torque_getvariable)(const char* name) = NULL;
- // Set a console variable
- void (*torque_setvariable)(const char* name, const char* value) = NULL;
- // Export a function to the Torque 3D console system which matches the StringCallback function prototype
- // specify the nameSpace, functionName, usage, min and max arguments
- void (*torque_exportstringcallback)(StringCallback cb, const char *nameSpace, const char *funcName, const char* usage, int minArgs, int maxArgs) = NULL;
- // Set a TorqueScript console function as secure and available for JavaScript via the callScript plugin method
- void (*torque_addsecurefunction)(const char* nameSpace, const char* fname) = NULL;
- // Call a TorqueScript console function that has been marked as secure
- const char* (*torque_callsecurefunction)(const char* nameSpace, const char* name, int argc, const char ** argv) = NULL;
- // resize the Torque 3D child window to the specified width and height
- void (*torque_resizewindow)(int width, int height) = NULL;
- #ifndef WIN32
- // On Mac, handle the parent safari window
- void (*torque_setsafariwindow)(NSWindow* window, int32 x, int32 y, int32 width, int32 height) = NULL;
- // On Mac, sets the executable path
- void (*torque_setexecutablepath)(const char *path) = NULL;
- #else
- // retrieve the render windows hwnd
- void* (*torque_gethwnd)() = NULL;
- // directly add a message to the Torque 3D event queue, bypassing the Windows event queue
- // this is useful in the case of the IE plugin, where we are hooking into an application
- // level message, and posting to the windows queue would cause a hang
- void (*torque_directmessage)(unsigned int message, unsigned int wparam, unsigned int lparam) = NULL;
- #endif
- };
- namespace WebCommon
- {
- std::string gPluginMIMEType;
- #ifdef WIN32
- HMODULE gTorque3DModule = NULL;
- HMODULE gPluginModule = 0;
- // bring up a platform specific message box (used for error reporting)
- void MessageBox(void* parentWindow, const char* msg, const char* caption )
- {
- ::MessageBoxA( (HWND) parentWindow, msg, caption, MB_OK|MB_ICONWARNING);
- }
- // retrieve the game directory using the filename (which includes the full path) of the plugin DLL
- const char* GetGameDirectory()
- {
- static char dir[4096];
- GetModuleFileNameA(gPluginModule, dir, 4096);
- int i = strlen(dir) - 1;
- while (i>=0)
- {
- if (dir[i] == '\\' || dir[i] == '/')
- {
- dir[i] = 0;
- break;
- }
- i--;
- }
- return dir;
- }
- // retrieve the name of our game DLL (includes Torque 3D engine) based on naming convention
- const char* GetGameLibrary()
- {
- char dir[4096];
- static char lib[4096];
- lib[0] = 0;
- GetModuleFileNameA(gPluginModule, dir, 4096);
- int i = strlen(dir) - 1;
- while (i>=0)
- {
- if (dir[i] == '\\' || dir[i] == '/')
- {
- // copy, minus the "NP " or "IE " of plugin name
- #ifdef _DEBUG
- sprintf(lib, "%s_DEBUG.dll", &dir[i+4]);
- #else
- sprintf(lib, "%s.dll", &dir[i+4]);
- #endif
- return lib;
- }
- // strip off end
- if (!strncmp(&dir[i], " Plugin", 7))
- dir[i] = 0;
- i--;
- }
- return lib;
- }
- #else
- void* gTorque3DModule = NULL;
- NSBundle* gPluginBundle = NULL;
- // bring up a platform specific message box (used for error reporting)
- void MessageBox(void* parentWindow, const char* msg, const char* caption )
- {
- // convert title and message to NSStrings
- NSString *nsTitle = [NSString stringWithUTF8String:caption];
- NSString *nsMessage = [NSString stringWithUTF8String:msg];
- NSAlert *alert = [NSAlert alertWithMessageText:nsTitle
- defaultButton:@"OK"
- alternateButton:nil
- otherButton:nil
- informativeTextWithFormat:nsMessage];
- [alert runModal];
- }
- NSBundle* GetPluginBundle()
- {
- if (gPluginBundle)
- return gPluginBundle;
- NSDictionary *mimeTypes;
- NSString *mime;
- NSEnumerator *f;
- NSArray *bundles = [NSBundle allBundles];
- for (int i = 0; i < [bundles count]; i++) {
- NSBundle *b = [bundles objectAtIndex:i];
- mimeTypes=[b objectForInfoDictionaryKey:@"WebPluginMIMETypes"];
- if (!mimeTypes)
- continue;
- f=[mimeTypes keyEnumerator];
- while((mime=[f nextObject]))
- {
- if (gPluginMIMEType == std::string([mime UTF8String]))
- {
- gPluginBundle = b;
- break;
- }
- }
- }
- return gPluginBundle;
- }
- // retrieve the game's install folder based on entries from our plugin's Info.plist
- const char* GetGameDirectory()
- {
- static char gamePath[2048] = {'\0'};
- if (gamePath[0])
- return gamePath;
- NSBundle* pluginBundle = GetPluginBundle();
- if (!pluginBundle)
- return NULL;
- NSString *gameInstallPathKey = [NSString stringWithUTF8String:"GameInstallPath"];
- NSString *gameInstallPath = [pluginBundle objectForInfoDictionaryKey: gameInstallPathKey];
- if (!gameInstallPath)
- return NULL;
- strcpy(gamePath, [gameInstallPath UTF8String]);
- if (!gamePath[0])
- return NULL;
- return gamePath;
- }
- // retrieve the game bundle (including Torque 3D engine) from the plugin Info.plist
- const char* GetGameLibrary()
- {
- static char libPath[2048] = {'\0'};
- if (libPath[0])
- return libPath;
- const char* gamePath = GetGameDirectory();
- if (!gamePath)
- return NULL;
- NSBundle* pluginBundle = GetPluginBundle();
- if (!pluginBundle)
- return NULL;
- // NSString* bundleIdentifier = [pluginBundle bundleIdentifier];
- NSString *gameNameKey = [NSString stringWithUTF8String:"GameName"];
- NSString *gameName = [pluginBundle objectForInfoDictionaryKey: gameNameKey];
- if (!gameName)
- return NULL;
- const char* cgameName = [gameName UTF8String];
- if (!cgameName[0])
- return NULL;
- #ifdef DEBUG
- sprintf(libPath, "%s%s_DEBUG.app/Contents/Frameworks/%s Bundle.bundle/Contents/MacOS/%s Bundle", gamePath, cgameName, cgameName, cgameName);
- #else
- sprintf(libPath, "%s%s.app/Contents/Frameworks/%s Bundle.bundle/Contents/MacOS/%s Bundle", gamePath, cgameName, cgameName, cgameName);
- #endif
- return libPath;
- }
- #endif
- bool ChangeToGameDirectory()
- {
- const char* gameDir = GetGameDirectory();
- if (!gameDir)
- return false;
- #ifdef WIN32
- return SetCurrentDirectoryA(gameDir);
- #else
- return (chdir(gameDir) == 0);
- #endif
- }
- // loads the Torque 3D shared library, sets web deployment mode, retrieves engine "C" interface
- bool InitTorque3D(void* platformWindow, int clipLeft, int clipTop, int clipRight, int clipBottom)
- {
- const char* gameDir = GetGameDirectory();
- const char* gameLib = GetGameLibrary();
- if (gTorque3DModule)
- {
- WebCommon::MessageBox( 0, "This plugin allows only one instance", "Error");
- return false;
- }
- if (!gameDir || !gameLib)
- {
- WebCommon::MessageBox( 0, "Unable to get game plugin information", "Error");
- return false;
- }
- if (!ChangeToGameDirectory())
- return false;
- std::string gameLibStr = gameLib;
- #ifdef WIN32
- // We want to use an absolute path to the game library
- gameLibStr = gameDir;
- WebCommon::ConvertToWindowsPathSep(gameLibStr);
- gameLibStr += "\\";
- gameLibStr += gameLib;
- #endif
- gTorque3DModule = TORQUE_OPEN(gameLibStr.c_str());
- if (!gTorque3DModule)
- {
- char error[4096];
- #ifdef WIN32
- sprintf(error, "Could not load game library: %s/%s. Please make sure you have the latest DirectX installed.", gameDir, gameLib);
- #else
- sprintf(error, "Could not load game library: %s/%s. ", gameDir, gameLib);
- #endif
- WebCommon::MessageBox( 0, error, "Error");
- return false;
- }
- // snag all the exported functions of the "C" interface
- torque_engineinit = (bool (*)(int argc, const char **argv))TORQUE_FUNCTION(gTorque3DModule, "torque_engineinit");
- torque_enginetick = (int (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_enginetick");
- torque_setwebdeployment = (int (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_setwebdeployment");
- torque_engineshutdown = (bool (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_engineshutdown");
- torque_enginesignalshutdown = (void (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_enginesignalshutdown");
- torque_reset = (void (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_reset");
- torque_evaluate = (const char* (*)(const char* code))TORQUE_FUNCTION(gTorque3DModule, "torque_evaluate");
- torque_getvariable = (const char* (*)(const char* name))TORQUE_FUNCTION(gTorque3DModule, "torque_getvariable");
- torque_setvariable = (void (*)(const char* name, const char* value))TORQUE_FUNCTION(gTorque3DModule, "torque_setvariable");
- torque_exportstringcallback = (void (*)(StringCallback cb, const char *nameSpace, const char *funcName, const char* usage, int minArgs, int maxArgs))TORQUE_FUNCTION(gTorque3DModule, "torque_exportstringcallback");
- torque_addsecurefunction = (void (*)(const char* nameSpace, const char* name))TORQUE_FUNCTION(gTorque3DModule, "torque_addsecurefunction");
- torque_callsecurefunction = (const char* (*)(const char* nameSpace, const char* name, int argc, const char ** argv))TORQUE_FUNCTION(gTorque3DModule, "torque_callsecurefunction");
- torque_resizewindow = (void (*)(int width, int height))TORQUE_FUNCTION(gTorque3DModule, "torque_resizewindow");
- // check that we got them all
- if (!torque_engineinit ||
- !torque_enginetick ||
- !torque_setwebdeployment ||
- !torque_engineshutdown ||
- !torque_enginesignalshutdown ||
- !torque_reset ||
- !torque_evaluate ||
- !torque_getvariable ||
- !torque_setvariable ||
- !torque_exportstringcallback ||
- !torque_addsecurefunction ||
- !torque_callsecurefunction ||
- !torque_resizewindow )
- {
- WebCommon::MessageBox( platformWindow, "The plugin could not be initialized (missing function exports)", "Error");
- TORQUE_CLOSE(gTorque3DModule);
- gTorque3DModule = NULL;
- return false;
- }
- #ifndef WIN32
- torque_setexecutablepath = (void (*)(const char *path)) dlsym(gTorque3DModule, "torque_setexecutablepath");
- torque_setsafariwindow = (void (*)(NSWindow* nswnd, int32, int32, int32, int32)) dlsym(gTorque3DModule, "torque_setsafariwindow");
- if (!torque_setexecutablepath || !torque_setsafariwindow)
- {
- WebCommon::MessageBox( platformWindow, "The plugin could not be initialized (missing function exports)", "Error");
- TORQUE_CLOSE(gTorque3DModule);
- gTorque3DModule = NULL;
- return false;
- }
- #else
- torque_gethwnd = (void* (*)())TORQUE_FUNCTION(gTorque3DModule, "torque_gethwnd");
- torque_directmessage = (void (*)(unsigned int message, unsigned int wparam, unsigned int lparam))TORQUE_FUNCTION(gTorque3DModule, "torque_directmessage");
- if (!torque_gethwnd || !torque_directmessage)
- {
- WebCommon::MessageBox( platformWindow, "The plugin could not be initialized (missing function exports)", "Error");
- TORQUE_CLOSE(gTorque3DModule);
- gTorque3DModule = NULL;
- return false;
- }
- #endif
- //tell Torque3D that we're a browser plugin
- torque_setwebdeployment();
- const char* args[3];
- int argc;
- #ifdef WIN32
- // windows uses a command line arg for parent window
- char parentWindow[256];
- argc = 3;
- sprintf(parentWindow, "%I64u", (unsigned __int64)platformWindow);
- args[0] = "game.exe"; //just to satisfy command line parsing
- args[1] = "-window";
- args[2] = parentWindow;
- #else
- NSWindow* browserWindow = (NSWindow*) platformWindow;
- // tell Torque 3D about our parent browser window
- // we initialize with zero size as the page hasn't completely loaded yet
- // so, the plugin hasn't been resized by the page and it is better to not show
- // anything than wrong extents
- torque_setsafariwindow( browserWindow, 0, 0, 0, 0);
- argc = 1;
- args[0] = gameDir; // just to satisfy command line parsing
- #endif
- // initialize Torque 3D!
- if (!torque_engineinit(argc, args))
- {
- WebCommon::MessageBox( platformWindow, "The plugin could not be initialized (internal initialization error)", "Error");
- return false;
- }
- return true;
- }
- // unloads the Torque 3D shared library (first signaling a shutdown for clean exit)
- void ShutdownTorque3D()
- {
- if (gTorque3DModule)
- {
- ChangeToGameDirectory();
- torque_enginesignalshutdown();
- torque_enginetick();
- torque_engineshutdown();
- TORQUE_CLOSE(gTorque3DModule);
- }
- gTorque3DModule = NULL;
- }
- // checks a given domain against the allowed domains in webConfig.h
- bool CheckDomain(const char* url)
- {
- bool domainCheck = true;
- #ifndef WEBDEPLOY_DOMAIN_CHECK
- domainCheck = false;
- #endif
- #ifdef DEBUG
- # ifdef WEBDEPLOY_DOMAIN_ALLOW_DEBUG
- domainCheck = false;
- # endif
- #endif
- if (!domainCheck)
- return true; // gets rid of "unreachable code" warning
- if (strlen(url) > 512)
- return false;
- if (strlen(url) < 5)
- return false;
- //do not allow file when using domain checking
- if (!strncasecmp(url,"file",4))
- return false;
- char curl[512] = {0};
- unsigned int begin = 0;
- while(url[begin])
- {
- if (url[begin] == ':')
- {
- if (begin + 3 > strlen(url))
- return false;
- begin+=3; //skip ://
- break;
- }
- begin++;
- }
- unsigned int end = begin;
- while(end < strlen(url))
- {
- if (url[end] == '/')
- {
- break;
- }
- end++;
- }
- strcpy(curl, &url[begin]);
- curl[end-begin] = 0;
- // iterate checking against our allowed domains
- for (int i = 0; gAllowedDomains[i]; i++)
- if (!strcasecmp(curl, gAllowedDomains[i]))
- return true;
- WebCommon::MessageBox( 0 , "This plugin cannot be executed from the domain specified", "Error");
- return false;
- }
- // exposes TorqueScript functions marked as secure in webConfig.h, these functions can then be called on the page via Javascript
- void AddSecureFunctions()
- {
- char snamespace[256];
- char fname[256];
- //define secure functions here
- for (unsigned int i = 0; gSecureScript[i]; i++)
- {
- snamespace[0] = 0;
- strcpy(fname, gSecureScript[i]);
- //scan through looking for namespace
- for (unsigned int j = 1; j < strlen(fname)-2; j++)
- {
- if (fname[j] == ':' && fname[j+1] == ':')
- {
- strcpy(snamespace, gSecureScript[i]);
- snamespace[j] = 0;
- strcpy(fname,&gSecureScript[i][j+2]);
- break;
- }
- }
- torque_addsecurefunction(snamespace, fname);
- }
- }
- //simple string copy that eats white space
- void StringCopy(char* dst, const char* src, int count)
- {
- int i, j;
- bool eat = true;
- for (i = 0, j = 0; i < count ; i++)
- {
- if (src[i] == 0)
- {
- dst[j] = 0;
- return;
- }
- if (src[i] != '"' && src[i] != '\t' && src[i] != '\n' && src[i] != ')' && src[i] != '(')
- {
- if (eat && src[i] == ' ')
- continue;
- if (src[i] == '\'')
- {
- eat = !eat;
- continue;
- }
- dst[j++] = src[i];
- }
- }
- }
- void SetVariable(const char* variable, const char* value)
- {
- char mvar[1024];
- char mvar2[1024];
- if (strlen(variable) > 1023)
- {
- WebCommon::MessageBox( 0, "WebCommon::SetVariable - buffer overrun", "Error");
- return;
- }
- // make local copies stripping off $ decorator is needed
- if (variable[0] == '$')
- strcpy(mvar, &variable[1]);
- else
- strcpy(mvar, variable);
- const char* js = "javascript::";
- if (strncasecmp(js, mvar, 12))
- sprintf(mvar2, "Javascript::%s", mvar);
- else
- strcpy(mvar2, mvar);
- torque_setvariable(mvar2, value);
- }
- const char* GetVariable(const char* variable)
- {
- char mvar[1024];
- char mvar2[1024];
- if (strlen(variable) > 1023)
- {
- WebCommon::MessageBox( 0, "WebCommon::GetVariable - buffer overrun", "Error");
- return "0";
- }
- // make local copies stripping off $ decorator is needed
- if (variable[0] == '$')
- strcpy(mvar, &variable[1]);
- else
- strcpy(mvar, variable);
- const char* js = "javascript::";
- if (strncasecmp(js, mvar, 12))
- sprintf(mvar2, "Javascript::%s", mvar);
- else
- strcpy(mvar2, mvar);
- return torque_getvariable(mvar2);
- }
- #ifdef WIN32
- // string conversion to/from wstring and string
- std::wstring StringToWString( const std::string& str )
- {
- size_t size = str.length();
- wchar_t* w = new wchar_t[size+1];
- memset( w, 0, sizeof(wchar_t) * (size+1) );
- MultiByteToWideChar( CP_ACP,
- 0,
- str.c_str(),
- size,
- w,
- size );
- std::wstring ws(w);
- delete[] w;
- return ws;
- }
- std::string WStringToString( const std::wstring& wstr )
- {
- size_t size = wstr.length();
- char* s = new char[size+1];
- memset( s, 0, sizeof(char) * (size+1) );
- WideCharToMultiByte( CP_ACP,
- 0,
- wstr.c_str(),
- size,
- s,
- size,
- NULL,
- NULL );
- std::string str(s);
- delete[] s;
- return str;
- }
- void ConvertToWindowsPathSep(std::string& path)
- {
- size_t pos = 0;
- while(pos < path.size() || pos != std::string::npos)
- {
- pos = path.find("/", pos);
- if(pos != std::string::npos)
- {
- path.replace(pos, 1, "\\");
- ++pos;
- }
- }
- }
- #endif
- } //namespace WebCommon
|