Пример #1
0
 internal static void Start()
 {
     YouTubeMessageHandlers.InvokeHandler(new YouTubeMessage("youtube#onInitialize"), "");
     TaskHelper.ScheduleUniqueActionAtTime("YouTubeOAuthRefresh", () => YouTubeOAuthToken.Refresh(), YouTubeOAuthToken.expireTime.Subtract(new TimeSpan(0, 1, 0)));
     TaskHelper.ScheduleUniqueRepeatingAction("YouTubeChannelRefresh", () => YouTubeLiveBroadcast.Refresh(), 60000 * 3); // Refresh our list of broadcasts 3 minutes (this task will automatically cancel it's self once it latches onto a broadcast)
     TaskHelper.ScheduleUniqueRepeatingAction("YouTubeLiveChatRefresh", () => YouTubeLiveChat.Refresh(), 0);
 }
Пример #2
0
        private static void HttpServer_OnGet(HttpRequestEventArgs e)
        {
            var request  = e.Request;
            var response = e.Response;

            byte[] data = null;

            switch (request.Url.LocalPath)
            {
            case "/callback":
                // If we successfully exchange our code for an auth token, request a listing of live broadcast info
                if (YouTubeOAuthToken.Exchange(request.QueryString["code"]))
                {
                    response.StatusCode = 307;
                    response.Redirect($"http://localhost:{port}/success");

                    // Start the YouTubeConnection
                    YouTubeConnection.Start();
                }
                else
                {
                    response.StatusCode = 401;
                    response.Redirect($"http://localhost:{port}/failure");
                }

                // Close the response then stop the server
                response.Close();
                break;

            case "/success":
                data = Encoding.UTF8.GetBytes("Success linking YouTube account! You may now close this page and return to the game.");
                response.WriteContent(data);
                response.StatusCode = 200;
                response.Close();
                StopServer();
                break;

            case "/failure":
                data = Encoding.UTF8.GetBytes("Failed to link YouTube account.");
                response.WriteContent(data);
                response.StatusCode = 200;
                response.Close();
                StopServer();
                break;

            default:
                response.StatusCode = 404;
                StopServer();
                break;
            }
        }
Пример #3
0
        internal static void Refresh()
        {
            try
            {
                // Wait a few seconds then return if the current broadcast is null
                if (YouTubeLiveBroadcast.currentBroadcast == null)
                {
                    Thread.Sleep(5000);
                    return;
                }

                //Plugin.Log($"Requesting chat messages for live chat with id {YouTubeChannel.liveOrDefaultChatId}...");
                HttpWebRequest web = (HttpWebRequest)WebRequest.Create($"https://www.googleapis.com/youtube/v3/liveChat/messages?liveChatId={YouTubeLiveBroadcast.currentBroadcast.snippet.liveChatId}&part=id%2Csnippet%2CauthorDetails{(_nextPageToken!=""? $"&pageToken={_nextPageToken}" : "")}");
                web.Method = "GET";
                web.Headers.Add("Authorization", $"{YouTubeOAuthToken.tokenType} {YouTubeOAuthToken.accessToken}");
                web.Accept = "application/json";

                using (HttpWebResponse resp = (HttpWebResponse)web.GetResponse())
                {
                    if (resp.StatusCode == HttpStatusCode.OK)
                    {
                        using (Stream dataStream = resp.GetResponseStream())
                        {
                            using (StreamReader reader = new StreamReader(dataStream))
                            {
                                string ret = reader.ReadToEnd();
                                Process(ret);
                                //Plugin.Log($"Chat: {ret}");
                            }
                        }
                    }
                    else
                    {
                        Plugin.Log($"Error: {resp.StatusCode.ToString()}");
                    }
                }
            }
            catch (WebException ex)
            {
                // Read the response and log it
                using (Stream dataStream = ex.Response.GetResponseStream())
                {
                    using (StreamReader reader = new StreamReader(dataStream))
                    {
                        var response = reader.ReadToEnd();
                        Plugin.Log($"Status: {ex.Status}, Response: {response}");

                        switch (((HttpWebResponse)ex.Response).StatusCode)
                        {
                        // If we hit an unauthorized exception, the users auth token has expired
                        case HttpStatusCode.Unauthorized:
                            // Try to refresh the users auth token, forcing it through even if our local timestamp says it's not expired
                            if (!YouTubeOAuthToken.Refresh(true))
                            {
                                YouTubeOAuthToken.Invalidate();
                                YouTubeOAuthToken.Generate();
                            }
                            break;

                        case HttpStatusCode.Forbidden:
                            var           json      = JSON.Parse(response);
                            List <string> errorList = new List <string>();
                            foreach (var error in json["error"]["errors"].AsArray)
                            {
                                errorList.Add(error.Value["reason"].Value);
                            }
                            YouTubeConnection.lastError = "Unable to retrieve YouTube live chat messages. Have you reached your quota? Error(s): " + string.Join(", ", errorList);
                            YouTubeMessageHandlers.InvokeHandler(new YouTubeMessage("youtube#onError"), "");
                            YouTubeLiveBroadcast.currentBroadcast = null;
                            YouTubeConnection.Stop();
                            break;
                        }
                    }
                }
                _pollingIntervalMillis = 3000;
            }
            catch (Exception ex)
            {
                Plugin.Log(ex.ToString());
                _pollingIntervalMillis = 3000;
            }
            Thread.Sleep(_pollingIntervalMillis);
        }
Пример #4
0
        internal static void Initialize_Internal()
        {
            if (!initialized)
            {
                YouTubeMessageHandlers.Initialize();

                initialized = true;
                Task.Run(() =>
                {
                    Plugin.Log("Initializing!");

                    string ClientIDPath = Path.Combine(Globals.DataPath, "YouTubeClientId.json");
                    if (!File.Exists(ClientIDPath))
                    {
                        Plugin.Log("YouTubeClientId.json does not exist!");
                        // Client id/secret don't exist, abort
                        return;
                    }

                    // Initialize our client id/secret
                    if (!YouTubeOAuthToken.Initialize(ClientIDPath))
                    {
                        Plugin.Log("Something went wrong when trying to read YouTubeClientId.json.");
                        // Something went wrong when trying to read client id/secret
                        return;
                    }

                    string tokenPath = Path.Combine(Globals.DataPath, "YouTubeOAuthToken.json");
                    if (!File.Exists(tokenPath))
                    {
                        Plugin.Log("YouTubeOAuthToken.json does not exist, generating new auth token!");
                        // If we haven't already retrieved an oauth token, generate a new one
                        YouTubeOAuthToken.Generate();
                        return;
                    }

                    Plugin.Log("Auth token file exists!");

                    // Read our oauth token in from file
                    if (!YouTubeOAuthToken.Update(File.ReadAllText(tokenPath), false))
                    {
                        Plugin.Log("Failed to parse oauth token file, generating new auth token!");
                        // If we fail to parse the file, generate a new oauth token
                        YouTubeOAuthToken.Generate();
                        return;
                    }

                    Plugin.Log("Success parsing oauth token file!");

                    // Check if our auth key is expired, and if so refresh it
                    if (!YouTubeOAuthToken.Refresh())
                    {
                        Plugin.Log("Failed to refresh access token, generating new auth token!");
                        // If we fail to refresh our access token, generate a new one
                        YouTubeOAuthToken.Generate();
                        return;
                    }

                    // Sleep for a second before connecting, to allow for other plugins to register their callbacks
                    Thread.Sleep(1000);

                    // Finally, request our live broadcast info if everything went well
                    Start();
                });
            }
        }
Пример #5
0
        internal static void Refresh()
        {
            try
            {
                Plugin.Log($"Requesting live broadcast info...");
                HttpWebRequest web = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/youtube/v3/liveBroadcasts?part=id%2Csnippet%2Cstatus&broadcastStatus=all&broadcastType=all&maxResults=50");
                web.Method = "GET";
                web.Headers.Add("Authorization", $"{YouTubeOAuthToken.tokenType} {YouTubeOAuthToken.accessToken}");
                web.Accept    = "application/json";
                web.UserAgent = "StreamCoreClient";

                using (HttpWebResponse resp = (HttpWebResponse)web.GetResponse())
                {
                    if (resp.StatusCode == HttpStatusCode.OK)
                    {
                        using (Stream dataStream = resp.GetResponseStream())
                        {
                            using (StreamReader reader = new StreamReader(dataStream))
                            {
                                string ret = reader.ReadToEnd();
                                if (Update(ret))
                                {
                                    channelName = GetChannelName(currentBroadcast.snippet.channelId);
                                    Plugin.Log("YouTube channel name: " + channelName);
                                    YouTubeMessageHandlers.InvokeHandler(new YouTubeMessage("youtube#onConnectedToLiveChat"), "");

                                    TaskHelper.CancelTask("YouTubeChannelRefresh");
                                    Plugin.Log($"There are currently {broadcasts.Count} broadcasts being tracked.");// Ret: {ret}");
                                }
                                //Plugin.Log($"Broadcast \"{broadcast.Value.snippet.title}\" (ID: {broadcast.Value.id}, ChannelID: {broadcast.Value.snippet.channelId}) with description \"{broadcast.Value.snippet.description}\" status is \"{broadcast.Value.status.recordingStatus}\"");
                            }
                        }
                    }
                    else
                    {
                        Plugin.Log($"Error: {resp.StatusCode}");
                    }
                }
            }
            catch (WebException ex)
            {
                // Read the response and log it
                using (Stream dataStream = ex.Response.GetResponseStream())
                {
                    using (StreamReader reader = new StreamReader(dataStream))
                    {
                        var response = reader.ReadToEnd();
                        Plugin.Log($"Status: {ex.Status}, Response: {response}");

                        switch (((HttpWebResponse)ex.Response).StatusCode)
                        {
                        // If we hit an unauthorized exception, the users auth token has expired
                        case HttpStatusCode.Unauthorized:
                            // Try to refresh the users auth token, forcing it through even if our local timestamp says it's not expired
                            if (!YouTubeOAuthToken.Refresh(true))
                            {
                                YouTubeOAuthToken.Invalidate();
                                YouTubeOAuthToken.Generate();
                            }
                            break;

                        case HttpStatusCode.Forbidden:
                            var           json      = JSON.Parse(response);
                            List <string> errorList = new List <string>();
                            foreach (var error in json["error"]["errors"].AsArray)
                            {
                                errorList.Add(error.Value["reason"].Value);
                            }
                            YouTubeConnection.lastError = "Unable to retrieve live broadcast data! Ensure you have configured the YouTube data API correctly, then try again. Error(s): " + string.Join(", ", errorList);
                            YouTubeMessageHandlers.InvokeHandler(new YouTubeMessage("youtube#onError"), "");
                            currentBroadcast = null;
                            YouTubeConnection.Stop();
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Plugin.Log(ex.ToString());
            }
        }