Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

617 lines
19 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #if defined( REPLAY_ENABLED )
  8. #include "replayyoutubeapi.h"
  9. #include "tier1/KeyValues.h"
  10. #include "replay/ireplaymovie.h"
  11. #include "replay/ireplaymoviemanager.h"
  12. #include "replay/genericclassbased_replay.h"
  13. #include "vgui/ISurface.h"
  14. #include "vgui/ILocalize.h"
  15. #include "vgui_controls/ProgressBar.h"
  16. #include "vgui_controls/TextEntry.h"
  17. #include "vgui_controls/ScrollBar.h"
  18. #include "confirm_dialog.h"
  19. #include "replay/vgui/replaybrowserdetailspanel.h"
  20. #include "base_gcmessages.pb.h"
  21. #include "youtubeapi.h"
  22. #include "steamworks_gamestats.h"
  23. #include "replayvideo.h"
  24. #include "gc_clientsystem.h"
  25. // memdbgon must be the last include file in a .cpp file!!!
  26. #include <tier0/memdbgon.h>
  27. using namespace vgui;
  28. static ConVar youtube_username( "youtube_username", "", FCVAR_ARCHIVE, "Username for YouTube." );
  29. //-----------------------------------------------------------------------------
  30. extern IReplayMovieManager *g_pReplayMovieManager;
  31. extern const char *COM_GetModDirectory();
  32. extern void GetYouTubeAPIKey( const char *pGameDir, bool bOnSteamPublic, const char **ppSource, const char **ppDeveloperTag, const char **ppDeveloperKey );
  33. //-----------------------------------------------------------------------------
  34. static bool HasInvalidCharacters( const char *pString )
  35. {
  36. while ( *pString != 0 )
  37. {
  38. switch ( *pString )
  39. {
  40. case '<': return true;
  41. case '>': return true;
  42. case '&': return true;
  43. }
  44. ++pString;
  45. }
  46. return false;
  47. }
  48. //-----------------------------------------------------------------------------
  49. void UploadOgsData( IReplayMovie *pMovie, bool bEnded = false, const char *pEndReason = NULL )
  50. {
  51. static int s_nUploadCounter = 0;
  52. KeyValues* pKVData = new KeyValues( "TF2ReplayUploads" );
  53. pKVData->SetInt( "UploadCounter", s_nUploadCounter++ );
  54. pKVData->SetInt( "ReplayHandle", (int)pMovie->GetReplayHandle() );
  55. const ReplayRenderSettings_t &RenderSettings = pMovie->GetRenderSettings();
  56. CFmtStr fmtResolution( "%ix%i", RenderSettings.m_nWidth, RenderSettings.m_nHeight );
  57. pKVData->SetString( "ResolutionID", fmtResolution.Access() );
  58. pKVData->SetString( "CodecID", ReplayVideo_GetCodec( ReplayVideo_FindCodecPresetFromCodec( RenderSettings.m_Codec ) ).m_pName );
  59. pKVData->SetInt( "MotionBlurQuality", RenderSettings.m_nMotionBlurQuality );
  60. pKVData->SetInt( "RenderQuality", RenderSettings.m_nEncodingQuality );
  61. pKVData->SetInt( "FPSUPF", RenderSettings.m_FPS.GetUnitsPerFrame() );
  62. pKVData->SetInt( "FPSUPS", RenderSettings.m_FPS.GetUnitsPerSecond() );
  63. if ( bEnded )
  64. {
  65. pKVData->SetInt( "EndUploadTime", GetSteamWorksSGameStatsUploader().GetTimeSinceEpoch() );
  66. pKVData->SetString( "EndUploadReasonID", pEndReason );
  67. }
  68. else
  69. {
  70. pKVData->SetInt( "StartUploadTime", GetSteamWorksSGameStatsUploader().GetTimeSinceEpoch() );
  71. }
  72. GetSteamWorksSGameStatsUploader().AddStatsForUpload( pKVData );
  73. }
  74. //-----------------------------------------------------------------------------
  75. class CYouTubeLoginWaitDialog : public CGenericWaitingDialog
  76. {
  77. DECLARE_CLASS_SIMPLE( CYouTubeLoginWaitDialog, CGenericWaitingDialog );
  78. public:
  79. CYouTubeLoginWaitDialog( IReplayMovie *pMovie, CConfirmDialog *pLoginDialog )
  80. : CGenericWaitingDialog( pLoginDialog->GetParent() )
  81. , m_pMovie( pMovie )
  82. , m_pLoginDialog( pLoginDialog )
  83. {
  84. }
  85. virtual void OnUserClose()
  86. {
  87. BaseClass::OnUserClose();
  88. YouTube_LoginCancel();
  89. ShowMessageBox( "#YouTube_LoginResults_Title", "#YouTube_LoginResults_Cancel", "#GameUI_OK" );
  90. }
  91. virtual void OnTick()
  92. {
  93. BaseClass::OnTick();
  94. eYouTubeLoginStatus loginStatus = YouTube_GetLoginStatus();
  95. switch ( loginStatus )
  96. {
  97. case kYouTubeLogin_NotLoggedIn:
  98. break;
  99. case kYouTubeLogin_LoggedIn:
  100. Close();
  101. PostMessage( m_pLoginDialog, new KeyValues("Command", "command", "cancel" ), NULL);
  102. YouTube_ShowUploadDialog( m_pMovie, m_pLoginDialog->GetParent() );
  103. break;
  104. case kYouTubeLogin_CouldNotConnect:
  105. Close();
  106. ShowMessageBox( "#YouTube_LoginResults_Title", "#YouTube_LoginResults_CouldNotConnect", "#GameUI_OK" );
  107. break;
  108. case kYouTubeLogin_Forbidden:
  109. Close();
  110. ShowMessageBox( "#YouTube_LoginResults_Title", "#YouTube_LoginResults_Forbidden", "#GameUI_OK" );
  111. break;
  112. case kYouTubeLogin_GenericFailure:
  113. default:
  114. Close();
  115. ShowMessageBox( "#YouTube_LoginResults_Title", "#YouTube_LoginResults_Failure", "#GameUI_OK" );
  116. break;
  117. }
  118. }
  119. private:
  120. IReplayMovie *m_pMovie;
  121. CConfirmDialog *m_pLoginDialog;
  122. };
  123. class CYouTubeUploadWaitDialog : public CGenericWaitingDialog
  124. {
  125. DECLARE_CLASS_SIMPLE( CYouTubeUploadWaitDialog, CGenericWaitingDialog );
  126. public:
  127. CYouTubeUploadWaitDialog( IReplayMovie *pMovie, const char *pTitle, const char *pDescription, YouTubeUploadHandle_t handle, vgui::Panel *pParent )
  128. : CGenericWaitingDialog( pParent )
  129. , m_pMovie( pMovie )
  130. , m_strTitle( pTitle )
  131. , m_strDescription( pDescription )
  132. , m_uploadHandle( handle )
  133. , m_iTick( 0 )
  134. {
  135. }
  136. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  137. {
  138. BaseClass::ApplySchemeSettings( pScheme );
  139. m_pProgressBar = dynamic_cast< ProgressBar * >( FindChildByName( "Progress" ) );
  140. }
  141. virtual void PerformLayout()
  142. {
  143. BaseClass::PerformLayout();
  144. if ( m_pProgressBar )
  145. {
  146. m_pProgressBar->SetVisible( true );
  147. m_pProgressBar->SetSegmentInfo( XRES(1), XRES(5) );
  148. }
  149. }
  150. virtual const char* GetResFile() const { return "resource/UI/YouTubeUploadWaitingDialog.res"; }
  151. virtual const char *GetResFilePathId() const { return "GAME"; }
  152. virtual void OnUserClose()
  153. {
  154. BaseClass::OnUserClose();
  155. YouTube_CancelUpload( m_uploadHandle );
  156. UploadOgsData( m_pMovie, true, "cancelled" );
  157. }
  158. virtual void OnTick()
  159. {
  160. BaseClass::OnTick();
  161. double ultotal = 0.0;
  162. double ulnow = 0.0;
  163. if ( YouTube_GetUploadProgress( m_uploadHandle, ultotal, ulnow ) == false )
  164. {
  165. Close();
  166. ShowMessageBox( "#YouTube_Upload_Title", "#YouTube_Upload_Failure", "#GameUI_OK" );
  167. }
  168. else if ( YouTube_IsUploadFinished( m_uploadHandle ) )
  169. {
  170. bool bSuccess = true;
  171. CUtlString strURLToVideo;
  172. CUtlString strURLToVideoStats;
  173. if ( YouTube_GetUploadResults( m_uploadHandle, bSuccess, strURLToVideo, strURLToVideoStats ) && bSuccess )
  174. {
  175. // mark movie uploaded
  176. m_pMovie->SetUploaded( true );
  177. m_pMovie->SetUploadURL( strURLToVideoStats.Get() );
  178. g_pReplayMovieManager->FlagMovieForFlush( m_pMovie, true );
  179. // update the UI
  180. CReplayDetailsPanel *pDetailsPanel = dynamic_cast< CReplayDetailsPanel *>( GetParent() );
  181. if ( pDetailsPanel )
  182. {
  183. pDetailsPanel->InvalidateLayout( true, false );
  184. }
  185. ShowMessageBox( "#YouTube_Upload_Title", "#YouTube_Upload_Success", "#GameUI_OK", NULL, GetParent() );
  186. // notify the GC
  187. uint64 uSessionId = g_pClientReplayContext->GetServerSessionId( m_pMovie->GetReplayHandle() );
  188. if ( uSessionId != 0 )
  189. {
  190. GCSDK::CProtoBufMsg< CMsgReplayUploadedToYouTube > msg( k_EMsgGCReplay_UploadedToYouTube );
  191. msg.Body().set_youtube_url( strURLToVideoStats.Get() );
  192. msg.Body().set_youtube_account_name( YouTube_GetLoginName() );
  193. msg.Body().set_session_id( uSessionId );
  194. GCClientSystem()->BSendMessage( msg );
  195. }
  196. surface()->PlaySound( "replay\\youtube_uploadfinished.wav" );
  197. UploadOgsData( m_pMovie, true, "completed" );
  198. // share on Steam Community
  199. if ( steamapicontext && steamapicontext->SteamRemoteStorage() )
  200. {
  201. CUtlString strPreviewFileName;
  202. AppId_t nConsumerAppId = steamapicontext->SteamUtils()->GetAppID();
  203. ERemoteStoragePublishedFileVisibility eVisibility = k_ERemoteStoragePublishedFileVisibilityPublic;
  204. SteamParamStringArray_t tags;
  205. tags.m_ppStrings = NULL;
  206. tags.m_nNumStrings = 0;
  207. // don't bother waiting for result
  208. SteamAPICall_t hSteamAPICall = steamapicontext->SteamRemoteStorage()->PublishVideo(
  209. k_EWorkshopVideoProviderNone, "",
  210. strURLToVideo.Get(),
  211. strPreviewFileName.Get(),
  212. nConsumerAppId,
  213. m_strTitle.Get(),
  214. m_strDescription.Get(),
  215. eVisibility,
  216. &tags
  217. );
  218. hSteamAPICall;
  219. }
  220. }
  221. else
  222. {
  223. ShowMessageBox( "#YouTube_Upload_Title", "#YouTube_Upload_Failure", "#GameUI_OK" );
  224. surface()->PlaySound( "replay\\youtube_uploadfailed.wav" );
  225. UploadOgsData( m_pMovie, true, "failed" );
  226. }
  227. // close wait dialog
  228. YouTube_ClearUploadResults( m_uploadHandle );
  229. Close();
  230. }
  231. else
  232. {
  233. float flProgress = MIN( ulnow / MAX( ultotal, 1.0 ), 1.0f );
  234. int iProgress = int( 100.0 * flProgress );
  235. int ulnow_kb = uint32( ulnow / 1024 );
  236. int ultotal_kb = uint32( ultotal / 1024 );
  237. if ( ulnow_kb == ultotal_kb )
  238. {
  239. // we tick at 500 ms, so this should be ok
  240. m_iTick = ( m_iTick + 1 ) % 4;
  241. switch ( m_iTick )
  242. {
  243. case 0: SetDialogVariable( "duration", g_pVGuiLocalize->Find( "YouTube_UploadFinishing1" ) ); break;
  244. case 1: SetDialogVariable( "duration", g_pVGuiLocalize->Find( "YouTube_UploadFinishing2" ) ); break;
  245. case 2: SetDialogVariable( "duration", g_pVGuiLocalize->Find( "YouTube_UploadFinishing3" ) ); break;
  246. case 3: SetDialogVariable( "duration", g_pVGuiLocalize->Find( "YouTube_UploadFinishing4" ) ); break;
  247. }
  248. }
  249. else
  250. {
  251. wchar_t wszProgress[1024];
  252. wchar_t wszPercentage[32];
  253. wchar_t wszNow[32];
  254. wchar_t wszTotal[32];
  255. _snwprintf( wszPercentage, ARRAYSIZE( wszPercentage ), L"%u", iProgress );
  256. _snwprintf( wszNow, ARRAYSIZE( wszNow ), L"%u", ulnow_kb );
  257. _snwprintf( wszTotal, ARRAYSIZE( wszTotal ), L"%u", ultotal_kb );
  258. g_pVGuiLocalize->ConstructString_safe( wszProgress, g_pVGuiLocalize->Find( "#YouTube_UploadProgress" ), 3,
  259. wszPercentage,
  260. wszNow,
  261. wszTotal );
  262. SetDialogVariable( "duration", wszProgress );
  263. }
  264. if ( m_pProgressBar )
  265. {
  266. m_pProgressBar->SetProgress( flProgress );
  267. }
  268. }
  269. }
  270. private:
  271. IReplayMovie *m_pMovie;
  272. YouTubeUploadHandle_t m_uploadHandle;
  273. CUtlString m_strTitle;
  274. CUtlString m_strDescription;
  275. ProgressBar *m_pProgressBar;
  276. int m_iTick;
  277. };
  278. //-----------------------------------------------------------------------------
  279. // Purpose: Dialog for logging into YouTube
  280. //-----------------------------------------------------------------------------
  281. class CYouTubeLoginDialog : public CConfirmDialog
  282. {
  283. DECLARE_CLASS_SIMPLE( CYouTubeLoginDialog, CConfirmDialog );
  284. public:
  285. CYouTubeLoginDialog( IReplayMovie *pMovie, Panel *pParent ) : BaseClass( pParent ), m_pMovie( pMovie ) {}
  286. const wchar_t *GetText() { return NULL; }
  287. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  288. {
  289. BaseClass::ApplySchemeSettings( pScheme );
  290. TextEntry *pTextEntryUserName = dynamic_cast< TextEntry * >( FindChildByName( "UserNameTextEntry" ) );
  291. if ( pTextEntryUserName )
  292. {
  293. pTextEntryUserName->SetText( "" );
  294. pTextEntryUserName->InsertString( youtube_username.GetString() );
  295. }
  296. }
  297. virtual void OnCommand( const char *command )
  298. {
  299. if ( !Q_strnicmp( command, "register", 8 ) )
  300. {
  301. if ( steamapicontext && steamapicontext->SteamFriends() )
  302. {
  303. steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( "http://www.youtube.com/create_account?next=/" );
  304. }
  305. }
  306. else if ( !Q_strnicmp( command, "confirm", 7 ) )
  307. {
  308. TextEntry *pTextEntryUserName = dynamic_cast< TextEntry * >( FindChildByName( "UserNameTextEntry" ) );
  309. TextEntry *pTextEntryPassword = dynamic_cast< TextEntry * >( FindChildByName( "PasswordTextEntry" ) );
  310. if ( pTextEntryUserName && pTextEntryPassword )
  311. {
  312. char szUserName[256];
  313. pTextEntryUserName->GetText( szUserName, sizeof( szUserName ) );
  314. char szPassword[256];
  315. pTextEntryPassword->GetText( szPassword, sizeof( szPassword ) );
  316. youtube_username.SetValue( szUserName );
  317. Login( szUserName, szPassword );
  318. }
  319. return;
  320. }
  321. BaseClass::OnCommand( command );
  322. }
  323. protected:
  324. virtual const char *GetResFile() { return "Resource/UI/YouTubeLoginDialog.res"; }
  325. virtual const char *GetResFilePathId() { return "GAME"; }
  326. void Login( const char* pUserName, const char *pPassword )
  327. {
  328. const bool bOnSteamPublic = GetUniverse() == k_EUniversePublic;
  329. const char *pGameDir = COM_GetModDirectory();
  330. const char *pSource = NULL;
  331. const char *pDeveloperTag = NULL;
  332. const char *pDeveloperKey = NULL;
  333. GetYouTubeAPIKey( pGameDir, bOnSteamPublic, &pSource, &pDeveloperTag, &pDeveloperKey );
  334. Assert( pSource );
  335. Assert( pDeveloperTag );
  336. Assert( pDeveloperKey );
  337. YouTube_SetDeveloperSettings( pDeveloperKey, pDeveloperTag );
  338. // try to log in
  339. YouTube_Login( pUserName, pPassword, pSource );
  340. CYouTubeLoginWaitDialog *pDialog = new CYouTubeLoginWaitDialog( m_pMovie, this );
  341. ShowWaitingDialog( pDialog, "#YouTube_LoggingIn", true, true, -1 );
  342. }
  343. private:
  344. IReplayMovie *m_pMovie;
  345. };
  346. //-----------------------------------------------------------------------------
  347. // Purpose: Dialog for uploading a file to YouTube
  348. //-----------------------------------------------------------------------------
  349. class CYouTubeUploadDialog : public CConfirmDialog
  350. {
  351. DECLARE_CLASS_SIMPLE( CYouTubeUploadDialog, CConfirmDialog );
  352. public:
  353. CYouTubeUploadDialog( IReplayMovie *pMovie, Panel *pParent ) : BaseClass( pParent ), m_pMovie( pMovie ) {}
  354. const wchar_t *GetText() { return NULL; }
  355. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  356. {
  357. BaseClass::ApplySchemeSettings( pScheme );
  358. m_pTextEntryMovieTitle = dynamic_cast< TextEntry * >( FindChildByName( "MovieTitleTextEntry" ) );
  359. m_pTextEntryMovieDesc = dynamic_cast< TextEntry * >( FindChildByName( "MovieDescTextEntry" ) );
  360. // use insert, so that max characters is obeyed
  361. m_pTextEntryMovieTitle->InsertString( m_pMovie->GetItemTitle() );
  362. // @todo add steam profile to description
  363. m_pTextEntryMovieDesc->SetText( "" );
  364. m_pTextEntryMovieDesc->SetMultiline( true );
  365. m_pTextEntryMovieDesc->SetCatchEnterKey( true );
  366. m_pTextEntryMovieDesc->SetVerticalScrollbar( true );
  367. ScrollBar *pScrollbar = dynamic_cast< ScrollBar* >( m_pTextEntryMovieDesc->FindChildByName( "Scrollbar" ) );
  368. if ( pScrollbar )
  369. {
  370. pScrollbar->SetAutohideButtons( false );
  371. pScrollbar->SetScrollbarButtonsVisible( true );
  372. }
  373. m_pUnlistedCheckbox = dynamic_cast< CheckButton * >( FindChildByName( "UnlistedCheckbox" ) );
  374. if ( m_pUnlistedCheckbox )
  375. {
  376. m_pUnlistedCheckbox->SetMouseInputEnabled( true );
  377. }
  378. }
  379. void GetGameNameStrings( const char **ppShortGameName, const char **ppFullGameName )
  380. {
  381. const char *pGameDir = COM_GetModDirectory();
  382. // Team Fortress 2?
  383. if ( FStrEq( pGameDir, "tf" ) )
  384. {
  385. *ppShortGameName = "TF2";
  386. *ppFullGameName = "Team Fortress 2";
  387. }
  388. // Team Fortress 2 Beta?
  389. else if ( FStrEq( pGameDir, "tf_beta" ) )
  390. {
  391. *ppShortGameName = "TF2";
  392. *ppFullGameName = "Team Fortress 2 Beta";
  393. }
  394. // Counter-Strike: Source?
  395. else if ( FStrEq( pGameDir, "cstrike" ) )
  396. {
  397. *ppShortGameName = "CSS";
  398. *ppFullGameName = "Counter-Strike: Source";
  399. }
  400. // Counter-Strike: Source Beta?
  401. else if ( FStrEq( pGameDir, "cstrike_beta" ) )
  402. {
  403. *ppShortGameName = "CSS";
  404. *ppFullGameName = "Counter-Strike: Source Beta";
  405. }
  406. else
  407. {
  408. AssertMsg( 0, "Unknown game" );
  409. *ppShortGameName = "";
  410. *ppFullGameName = "";
  411. }
  412. }
  413. virtual void OnCommand( const char *command )
  414. {
  415. if ( !Q_strnicmp( command, "termsofservice", 14 ) )
  416. {
  417. if ( steamapicontext && steamapicontext->SteamFriends() )
  418. {
  419. steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( "http://www.youtube.com/t/terms" );
  420. }
  421. }
  422. else if ( !Q_strnicmp( command, "confirm", 7 ) )
  423. {
  424. char szTitle[256];
  425. m_pTextEntryMovieTitle->GetText( szTitle, sizeof( szTitle ) );
  426. char szDesc[2048];
  427. m_pTextEntryMovieDesc->GetText( szDesc, sizeof( szDesc ) );
  428. if ( HasInvalidCharacters( szTitle ) )
  429. {
  430. ShowMessageBox( "#YouTube_Upload_Title", "#YouTube_Upload_InvalidChars_Title", "#GameUI_OK" );
  431. return;
  432. }
  433. if ( HasInvalidCharacters( szDesc ) )
  434. {
  435. ShowMessageBox( "#YouTube_Upload_Title", "#YouTube_Upload_InvalidChars_Desc", "#GameUI_OK" );
  436. return;
  437. }
  438. CGenericClassBasedReplay *pReplay = ToGenericClassBasedReplay( m_pMovie->GetItemReplay() );
  439. CFmtStr fmtMovieFullFilename( "%s%s", g_pReplayMovieManager->GetRenderDir(), m_pMovie->GetMovieFilename() );
  440. const char *pMimeType = "video/mp4";
  441. const char *pTitle = szTitle;
  442. const char *pCategory = "Games";
  443. // add steam profile to the description for verification if necessary
  444. EUniverse eSteamUniverse = GetUniverse();
  445. CUtlString description( szDesc );
  446. if ( steamapicontext && steamapicontext->SteamUser() )
  447. {
  448. const char *pchCommunityURL = "http://steamcommunity.com/";
  449. switch ( eSteamUniverse )
  450. {
  451. case k_EUniverseDev:
  452. pchCommunityURL = "http://localhost/community/";
  453. break;
  454. case k_EUniverseBeta:
  455. pchCommunityURL = "http://beta.steamcommunity.com/";
  456. break;
  457. case k_EUniversePublic:
  458. default:
  459. pchCommunityURL = "http://steamcommunity.com/";
  460. }
  461. description.Format( "%s\n\n%sprofiles/%llu", szDesc, pchCommunityURL, steamapicontext->SteamUser()->GetSteamID().ConvertToUint64() );
  462. }
  463. const char *pShortGameName = NULL;
  464. const char *pFullGameName = NULL;
  465. GetGameNameStrings( &pShortGameName, &pFullGameName );
  466. CFmtStr1024 keywords( "%s Replay, %s, %s, Replay, Valve, %s", pShortGameName, pShortGameName, pFullGameName, pReplay->GetPlayerClass() );
  467. bool bUnlisted = m_pUnlistedCheckbox->IsSelected();
  468. uint64 uSessionId = g_pClientReplayContext->GetServerSessionId( pReplay->GetHandle() );
  469. if ( uSessionId != 0 )
  470. {
  471. char szSessionId[32];
  472. // Write session ID as hex (this code taken from KeyValues.cpp, modified).
  473. #ifdef WIN32
  474. Q_snprintf( szSessionId, sizeof( szSessionId ), "%I64X", uSessionId );
  475. #else
  476. Q_snprintf( szSessionId, sizeof( szSessionId ), "%llX", uSessionId );
  477. #endif
  478. // Add the match tag to the list of keywords.
  479. keywords.AppendFormat( ", match_%s", szSessionId );
  480. }
  481. UploadOgsData( m_pMovie );
  482. YouTubeUploadHandle_t handle = YouTube_Upload( fmtMovieFullFilename.Access(), pMimeType, pTitle, description.Get(), pCategory, keywords.Access(), bUnlisted ? kYouTubeAccessControl_Unlisted : kYouTubeAccessControl_Public );
  483. if ( handle != NULL )
  484. {
  485. // Play a sound
  486. surface()->PlaySound( "replay\\youtube_startingupload.wav" );
  487. CYouTubeUploadWaitDialog *pDialog = new CYouTubeUploadWaitDialog( m_pMovie, pTitle, description.Get(), handle, GetParent() );
  488. ShowWaitingDialog( pDialog, "#YouTube_Uploading", true, true, -1 );
  489. // get rid of this dialog
  490. FinishUp();
  491. }
  492. else
  493. {
  494. ShowMessageBox( "#YouTube_Upload_Title", "#YouTube_Upload_Failure", "#GameUI_OK" );
  495. }
  496. return;
  497. }
  498. BaseClass::OnCommand( command );
  499. }
  500. protected:
  501. virtual const char *GetResFile() { return "Resource/UI/YouTubeUploadDialog.res"; }
  502. virtual const char *GetResFilePathId() { return "GAME"; }
  503. private:
  504. IReplayMovie *m_pMovie;
  505. TextEntry *m_pTextEntryMovieTitle;
  506. TextEntry *m_pTextEntryMovieDesc;
  507. CheckButton *m_pUnlistedCheckbox;
  508. };
  509. //-----------------------------------------------------------------------------
  510. void YouTube_ShowLoginDialog( IReplayMovie *pMovie, vgui::Panel *pParent )
  511. {
  512. CYouTubeLoginDialog *pDialog = vgui::SETUP_PANEL( new CYouTubeLoginDialog( pMovie, pParent ) );
  513. pDialog->Show( false );
  514. }
  515. //-----------------------------------------------------------------------------
  516. void YouTube_ShowUploadDialog( IReplayMovie *pMovie, vgui::Panel *pParent )
  517. {
  518. CYouTubeUploadDialog *pDialog = vgui::SETUP_PANEL( new CYouTubeUploadDialog( pMovie, pParent ) );
  519. pDialog->Show( false );
  520. }
  521. //-----------------------------------------------------------------------------
  522. #endif // REPLAY_ENABLED