bool CScriptEngine::CreateScriptEngine (void) { // Lua does not use scripting engine if (m_strLanguage.CompareNoCase ("Lua") == 0) { OpenLua (); return false; } // end of Lua // not under Wine if (bWine) return true; try { CLSID clsid; OLECHAR wszOutput[101]; /* Note: very, very important! To use swprintf successfully, you must specify %S for converting a single-byte string to a wide string, not %s. Alternatively, you can specify %hs which means the same thing. See reference to wprintf for details. If you don't, be prepared for access violations as the swprintf goes mad and writes all over memory, depending on whether there are two consecutive nulls in the string being printed. */ // avoid warning with more modern compiler #define _CRT_NON_CONFORMING_SWPRINTFS 1 // CString strFixedLanguage = m_strLanguage; // // strFixedLanguage.MakeLower (); // // if (strFixedLanguage == "rubyscript") // swprintf(wszOutput, OLESTR("%S"), "GlobalRubyScript"); // else swprintf(wszOutput, OLESTR("%S"), (LPCTSTR) m_strLanguage.Left (100)); CString strMsg; strMsg.Format ("finding CLSID of scripting language \"%s\"", (LPCTSTR) m_strLanguage); // javascript: {f414c260-6ac0-11cf-b6d1-00aa00bbbb58} // jscript: {f414c260-6ac0-11cf-b6d1-00aa00bbbb58} ??? // python: {DF630910-1C1D-11d0-AE36-8C0F5E000000} if (ShowError (CLSIDFromProgID(wszOutput, &clsid), strMsg)) return true; // create an instance of the VBscript/perlscript/jscript engine if (ShowError (::CoCreateInstance(clsid, NULL, CLSCTX_ALL, // CLSCTX_INPROC_SERVER, IID_IActiveScript, reinterpret_cast<void**>(&m_IActiveScript)), "loading scripting engine")) return true; if (ShowError (m_IActiveScript->QueryInterface( IID_IActiveScriptParse, reinterpret_cast<void**>(&m_IActiveScriptParse)), "locating parse interface")) return true; if (ShowError (m_IActiveScriptParse->InitNew (), "initialising scripting engine")) return true; // create host site object m_site = new CActiveScriptSite (m_pDoc->GetIDispatch (TRUE), m_pDoc); m_site->AddRef (); if (ShowError (m_IActiveScript->SetScriptSite (m_site), "setting site")) return true; // add world object to engine's namespace // added SCRIPTITEM_GLOBALMEMBERS in 3.27 WCHAR charWorld[]=L"world"; if (ShowError (m_IActiveScript->AddNamedItem (charWorld, SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE | SCRIPTITEM_GLOBALMEMBERS), "adding world to script engine")) return true; // if (ShowError (m_IActiveScript->AddNamedItem (L"world", // SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE | SCRIPTITEM_GLOBALMEMBERS), // "adding world to script engine")) // return true; // set state to started if (ShowError (m_IActiveScript->SetScriptState (SCRIPTSTATE_STARTED), "starting script engine")) return true; // connect outbound objects (ie. world) if (ShowError (m_IActiveScript->SetScriptState (SCRIPTSTATE_CONNECTED), "connecting script engine")) return true; // get script engine dispatch pointer if (ShowError (m_IActiveScript->GetScriptDispatch (0, &m_pDispatch), "getting script engine dispatch pointer")) return true; } // end of try block catch (HRESULT hr) { ShowError (hr, "starting scripting support"); DisableScripting (); return true; } catch (...) { ::TMessageBox ("Something nasty happened whilst initialising the scripting engine"); throw; } return false; } // end of CScriptEngine::CreateScriptEngine
bool CScriptEngine::ShowError (const HRESULT hr, const CString strMsg) { DWORD status = 0; char *formattedmsg; CString str; if (hr == S_OK) return false; const char * sForeColour = "darkorange"; const char * sBackColour = "black"; CScriptErrorDlg dlg; dlg.m_iError = hr; dlg.m_strEvent = strMsg; if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, LANG_NEUTRAL, (LPTSTR) &formattedmsg, 0, NULL)) { status = GetLastError (); dlg.m_strDescription.Format ("<<Unable to convert error number %ld>>", hr); } else { dlg.m_strDescription.Format ("Error %ld occurred when %s:\n\n%s", hr, (LPCTSTR) strMsg, formattedmsg); LocalFree (formattedmsg); } DisableScripting (); dlg.m_strRaisedBy = "No active world"; if (m_pDoc) { if (m_pDoc->m_CurrentPlugin) { dlg.m_strRaisedBy = "Plugin: " + m_pDoc->m_CurrentPlugin->m_strName; dlg.m_strRaisedBy += " (called from world: " + m_pDoc->m_mush_name + ")"; } else dlg.m_strRaisedBy = "World: " + m_pDoc->m_mush_name; } if (!m_pDoc || !m_pDoc->m_bScriptErrorsToOutputWindow) { if (m_pDoc) dlg.m_bHaveDoc = true; dlg.DoModal (); if (m_pDoc && dlg.m_bUseOutputWindow) { m_pDoc->m_bScriptErrorsToOutputWindow = true; m_pDoc->SetModifiedFlag (TRUE); } } else { m_pDoc->ColourNote (sForeColour, sBackColour, strMsg); m_pDoc->ColourNote (sForeColour, sBackColour, dlg.m_strRaisedBy); // m_pDoc->ColourNote (sForeColour, sBackColour, dlg.m_strCalledBy); m_pDoc->ColourNote (sForeColour, sBackColour, dlg.m_strDescription); } return true; } // end of CScriptEngine::ShowError
CMUSHclientDoc::~CMUSHclientDoc() { int i; // stop sounds playing, release sound buffers for (i = 0; i < MAX_SOUND_BUFFERS; i++) if (m_pDirectSoundSecondaryBuffer [i]) { DWORD iStatus; if (SUCCEEDED (m_pDirectSoundSecondaryBuffer [i]->GetStatus (&iStatus)) && (iStatus & DSBSTATUS_PLAYING)) m_pDirectSoundSecondaryBuffer [i]->Stop (); m_pDirectSoundSecondaryBuffer [i]->Release (); } if (m_pTimerWnd) { m_pTimerWnd->DestroyWindow(); delete m_pTimerWnd; m_pTimerWnd = NULL; } for (i = 0; i < 8; i++) delete m_font [i]; delete m_input_font; if (m_hNameLookup) WSACancelAsyncRequest (m_hNameLookup); // cancel host name lookup in progress delete [] m_pGetHostStruct; // delete buffer used by host name lookup delete m_MapFailureRegexp; // delete regexp structure for mapping failures if (m_pSocket) { ShutDownSocket (*m_pSocket); delete m_pSocket; m_pSocket = NULL; } if (m_pChatListenSocket) { ShutDownSocket (*m_pChatListenSocket); delete m_pChatListenSocket; m_pChatListenSocket = NULL; } // UDP listening sockets for (map<int, UDPsocket *>::iterator udpSocketIterator = m_UDPsocketMap.begin (); udpSocketIterator != m_UDPsocketMap.end (); udpSocketIterator++) delete udpSocketIterator->second; // delete chat sessions DELETE_LIST (m_ChatList); // delete plugins // we have to do it this way, because otherwise if a plugin attempts to access the // plugin list (eg. BroadcastPlugin, Trace) during the delete operation, then it // may call a plugin that was deleted a moment ago, but is still in the list. for (PluginListIterator pit = m_PluginList.begin (); pit != m_PluginList.end (); pit = m_PluginList.erase (pit)) // erase from list and get next one delete *pit; // delete *this* one CloseLog (); // this writes out the log file postamble as well // delete triggers DELETE_MAP (m_TriggerMap, CTrigger); // delete aliass DELETE_MAP (m_AliasMap, CAlias); // delete lines list DELETE_LIST (m_LineList); // delete timer map DELETE_MAP (m_TimerMap, CTimer); // delete variables map DELETE_MAP (m_VariableMap, CVariable); // delete Element map DELETE_MAP (m_CustomElementMap, CElement); // delete active tags list DELETE_LIST (m_ActiveTagList); // delete actions list DELETE_LIST (m_ActionList); // get rid of our positions array delete [] m_pLinePositions; // one less document gdoccount--; // update activity window App.m_bUpdateActivity = TRUE; // ****************** release scripting stuff DisableScripting (); if (!bWine) AfxOleUnlockApp(); // not needed? // free compression stuff if (m_CompressOutput) free (m_CompressOutput); if (m_CompressInput) free (m_CompressInput); // don't wrap up if not initialised if (m_bCompressInitOK) inflateEnd (&m_zCompress); // don't need to know what the configuration was any more DeleteConfigurationArrays (); // delete our arrays for (tStringMapOfMaps::iterator it = m_Arrays.begin (); it != m_Arrays.end (); it++) { tStringToStringMap * m = it->second; m->clear (); delete m; } // destroy accelerator table, if we had one if (m_accelerator) DestroyAcceleratorTable (m_accelerator); // if they loaded a special font, get rid of it RemoveSpecialFonts (); #ifdef PANE // get rid of owned panes safe_for_each (m_PaneMap.begin (), m_PaneMap.end (), closepane); #endif // PANE // delete MiniWindow map for (MiniWindowMapIterator mwit = m_MiniWindows.begin (); mwit != m_MiniWindows.end (); mwit++) delete mwit->second; m_MiniWindowsOrder.clear (); // delete databases for (tDatabaseMapIterator dbit = m_Databases.begin (); dbit != m_Databases.end (); dbit++) { if (dbit->second->pStmt) // finalize any outstanding statement sqlite3_finalize(dbit->second->pStmt); if (dbit->second->db) // and close the database sqlite3_close(dbit->second->db); delete dbit->second; // now delete memory used by it } } // end of CMUSHclientDoc::~CMUSHclientDoc