bool CRecorder::RunInit() { ASSERT(m_IsRecording); // assume CEngine::RunInit unhooked us by recreating routes m_IsHooking = FALSE; return(HookOutput()); }
// Execute command on server from remove client with redirected console output // Output will be sent back to client as "svc_print" command static void cRemoteCommand(int argc, char **argv) { guard(SVC_RemoteCommand); if (!rcon_password->string[0] || strcmp(argv[1], rcon_password->string)) { appPrintf("Bad rcon from %s:\n%s\n", NET_AdrToString(&net_from), net_message.data+4); Netchan_OutOfBandPrint(NS_SERVER, net_from, "print\nBad rcon password\n"); } else { appPrintf("Rcon from %s:\n%s\n", NET_AdrToString(&net_from), net_message.data+4); // fill line with a rest of command string (cut "rcon") TString<256> Cmd; Cmd[0] = 0; for (int i = 2; i < argc; i++) { if (i > 2) Cmd += " "; Cmd += argv[i]; } // execute command with a redirected output //?? may be, if message is longer, than MAX_MSGLEN_OLD, flush and continue //?? buffering output COutputDeviceMem *Mem = new COutputDeviceMem(MAX_MSGLEN_OLD-16); Mem->NoColors = true; // client may not support colored texts ... HookOutput(Mem); TRY { if (!ExecuteCommand(Cmd)) appWPrintf("Bad remote command \"%s\"\n", *Cmd); //?? move code to Mem->Flush(); call Flush() implicitly at end too // if server will be restarted during active redirection, drop data if (sv_client && sv_client->netchan.message.maxsize) { // send redirected text MSG_WriteByte(&sv_client->netchan.message, svc_print); MSG_WriteByte(&sv_client->netchan.message, PRINT_HIGH); MSG_WriteString(&sv_client->netchan.message, Mem->GetText()); } } CATCH { UnhookOutput; delete Mem; THROW_AGAIN; } END_CATCH UnhookOutput; delete Mem; } unguard; }
bool CRecorder::Start(LPCTSTR Path, const CRecordInfo& Info, const CVideoComprState *ComprState) { if (!Open(Path, Info, ComprState)) return(FALSE); // create frame surface and surface description if (!m_Engine->GetRenderer().CreateSurface(m_SurfDesc, m_FrameSurf)) return(FALSE); // create output device context and bitmap CClientDC dc(theApp.GetMain()); if (!m_OutDC.CreateCompatibleDC(&dc)) { AfxMessageBox(IDS_REC_CANT_CREATE_DC); return(FALSE); } WORD BitCount = static_cast<WORD>(m_RecInfo.m_BitCount); CSize OutFrameSize = m_RecInfo.m_OutFrameSize; if (!m_OutDib.Create(OutFrameSize.cx, OutFrameSize.cy, BitCount)) { AfxMessageBox(IDS_REC_CANT_CREATE_BITMAP); return(FALSE); } m_PrevBmp = m_OutDC.SelectObject(m_OutDib); m_OutDC.SetStretchBltMode(HALFTONE); // create input queue and thread DWORD Timeout = m_Engine->GetFrameTimeout(); if (!m_InputQueue.Create(CEngine::PLUGIN_QUEUE_SIZE, m_Engine->GetStopEvent(), Timeout)) { AfxMessageBox(IDS_REC_CANT_CREATE_QUEUE); return(FALSE); } m_Frame = NULL; if (!CEngineThread::Create(ThreadFunc, this, m_Engine->GetPriority(), 0, Timeout)) { AfxMessageBox(IDS_REC_CANT_CREATE_THREAD); return(FALSE); } m_IsEnding = FALSE; if (m_Engine->IsRunning()) { // if engine running if (!HookOutput()) // divert last plugin's frames to our input queue return(FALSE); if (!m_Engine->IsPaused()) { if (!CEngineThread::Run(TRUE)) { // start our thread AfxMessageBox(IDS_REC_CANT_START_THREAD); return(FALSE); } } } // otherwise RunInit hooks output and Run starts our thread m_IsRecording = TRUE; return(TRUE); }