/// <summary> /// Sets a memory to a specific value in a playthrough. /// </summary> /// <param name="token">Provide the token of the play-through where the memory should be changed.</param> /// <param name="recallValue">The recall value of the memory.</param> /// <param name="saveValue">The new value of the memory.</param> /// <param name="callback">Called when the mood has successfully been set.</param> public static void SetMemory(string token, string recallValue, string saveValue, Action callback = null) { var memory = new SetMemoryParams(recallValue, saveValue); var request = new HTTPRequest( new Uri($"{BaseUrl}/play/set-memory/"), HTTPMethods.Post, ( (originalRequest, response) => { if (!response.IsSuccess) { Debug.LogError("Error:" + originalRequest.Response.DataAsText); return; } CharismaLogger.Log($"Set memory - '{memory.memoryRecallValue}' with value '{memory.saveValue}'"); callback?.Invoke(); })) { RawData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(memory)) }; request.SetHeader("Authorization", $"Bearer {token}"); request.AddHeader("Content-Type", "application/json"); request.Send(); }
/// <summary> /// Initialise a new conversation in a play-through. /// </summary> /// <param name="token">Valid play-through token.</param> /// <param name="callback">Called when a conversation has been generated.</param> public static void CreateConversation(string token, Action <int> callback) { var request = new HTTPRequest(new Uri($"{BaseUrl}/play/conversation/"), HTTPMethods.Post, ( (originalRequest, response) => { if (!response.IsSuccess) { Debug.LogError("Error:" + originalRequest.Response.DataAsText); return; } var data = Encoding.UTF8.GetString(response.Data); try { var deserialized = JsonConvert.DeserializeObject <CreateConversationResponse>(data); callback?.Invoke(deserialized.ConversationId); CharismaLogger.Log("Conversation request complete"); } catch (Exception e) { Debug.LogError($"Could not generate conversation; {e}"); throw; } })) { RawData = Encoding.UTF8.GetBytes(token) }; request.SetHeader("Authorization", $"Bearer {token}"); request.Send(); CharismaLogger.Log("Requesting conversation"); }
private IEnumerator GenerateAudio(SpeechOptions options, byte[] data, Action <AudioClip> action) { switch (options.encoding) { case "mp3": { var tempFile = Application.persistentDataPath + "/bytes.mp3"; if (Data != null) { File.WriteAllBytes(tempFile, Data); } var clip = new WWW("file://" + tempFile); while (!clip.isDone) { yield return(null); } // GenerateAudio the clip Clip = FromMp3Data(clip.bytes); action.Invoke(Clip); CharismaLogger.Log("Generated audio"); break; } case "ogg": { var tempFile = Application.persistentDataPath + "/bytes.ogg"; if (Data != null) { File.WriteAllBytes(tempFile, Data); } var clip = new WWW("file://" + tempFile); while (!clip.isDone) { yield return(null); } // GenerateAudio the clip Clip = clip.GetAudioClip(false, false, AudioType.OGGVORBIS); action.Invoke(Clip); CharismaLogger.Log("Generated audio"); break; } default: throw new NotImplementedException(); } }
/// <summary> /// Send a tap event to Charisma. /// </summary> /// <param name="conversationId">Id of the conversation the tap should be sent to.</param> public void Tap(int conversationId) { if (!IsReadyToPlay) { Debug.LogError("Charisma: Socket not open. Connect before starting the interaction"); return; } ; var tapOptions = new Tap(conversationId, _speechOptions); CharismaLogger.Log("Sending `tap` event to Charisma"); _socket?.Emit("tap", tapOptions); }
/// <summary> /// Send player response to Charisma. /// </summary> /// <param name="message">Message to send.</param> /// <param name="conversationId">Conversation to interact with.</param> public void Reply(int conversationId, string message) { if (!IsReadyToPlay) { Debug.LogError("Charisma: Socket not open. Connect before starting the interaction"); return; } ; var playerMessage = new Reply(message, conversationId, _speechOptions); CharismaLogger.Log($"Sending `reply` event to Charisma:\nMessage: {message}\nConversation: {conversationId}"); _socket?.Emit("reply", playerMessage); }
public static void Setup() { try { // Create the coroutine consumer Object.Instantiate(Resources.Load <MainThreadConsumer>("Prefabs/MainThreadConsumer")); } catch (Exception e) { Debug.LogError($"Error: Failed to set up properly! {e}"); throw; } CharismaLogger.Log("Playthrough successfully set up."); }
/// <summary> /// Start the story from selected scene. /// </summary> /// <param name="conversationId">Id of the conversation we want to resume.</param> /// <param name="speechOptions">Speech settings for the interaction.</param> public void Resume(int conversationId, SpeechOptions speechOptions = null) { if (!IsReadyToPlay) { Debug.LogError("Charisma: Socket not open. Connect before resuming the interaction"); return; } ; // Initialise speech options _speechOptions = speechOptions; var resumeOptions = new ResumeOptions(conversationId, _speechOptions); CharismaLogger.Log("Sending `resume` event to Charisma"); _socket?.Emit("resume", resumeOptions); }
/// <summary> /// Start the story from selected scene. /// </summary> /// <param name="sceneIndex">The scene to start from.</param> /// <param name="speechOptions">Speech settings for the interaction.</param> /// <param name="conversationId">Id of the conversation we want to start.</param> public void Start(int conversationId, int sceneIndex, SpeechOptions speechOptions = null) { if (!IsReadyToPlay) { Debug.LogError("Charisma: Socket not open. Connect before starting the interaction"); return; } ; // Initialise speech options _speechOptions = speechOptions; var startOptions = new StartOptions(conversationId, sceneIndex, speechOptions); CharismaLogger.Log("Sending `start` event to Charisma"); _socket?.Emit("start", startOptions); }
// Disconnect from the current interaction. public void Disconnect() { if (!_socket.IsOpen) { return; } try { _socket.Disconnect(); _socket = null; _socketManager.Close(); _socketManager = null; IsReadyToPlay = false; } catch (Exception e) { Debug.LogError($"Charisma: failed to disconnect: {e}"); return; } CharismaLogger.Log("Successfully disconnected"); }
/// <summary> /// Generate a new play-through. /// </summary> /// <param name="tokenParams">Settings object for this play-through</param> /// <param name="callback">Called when a valid token has been generated</param> public static void CreatePlaythroughToken(CreatePlaythroughTokenParams tokenParams, Action <string> callback) { var requestParams = tokenParams.StoryVersion != 0 ? Encoding.UTF8.GetBytes(JsonConvert.SerializeObject( new { storyId = tokenParams.StoryId, version = tokenParams.StoryVersion })) : Encoding.UTF8.GetBytes(JsonConvert.SerializeObject( new { storyId = tokenParams.StoryId })); var request = new HTTPRequest(new Uri($"{BaseUrl}/play/token/"), HTTPMethods.Post, ( (originalRequest, response) => { if (!response.IsSuccess) { Debug.LogError("Error:" + originalRequest.Response.DataAsText); return; } var data = Encoding.UTF8.GetString(response.Data); try { var deserialized = JsonConvert.DeserializeObject <CreatePlaythroughTokenResponse>(data); var token = deserialized.Token; callback?.Invoke(token); CharismaLogger.Log("Token request complete"); } catch (Exception e) { Debug.LogError($"Could not deserialize token. Are you using the correct API key?: {e}"); throw; } })) { RawData = requestParams }; // Only pass the API key if we are debugging if (tokenParams.StoryVersion == -1 && !string.IsNullOrEmpty(tokenParams.ApiKey)) { request.SetHeader("Authorization", $"API-Key {tokenParams.ApiKey}"); CharismaLogger.Log("Using API key to generate playthrough"); } // If the API key is null or nonexistent, throw error if (tokenParams.StoryVersion == -1 && string.IsNullOrEmpty(tokenParams.ApiKey)) { Debug.LogError("Please provide an API key in order to play the draft version"); return; } if (tokenParams.StoryVersion == 0) { CharismaLogger.Log("Generating playthrough token with latest published version"); } if (tokenParams.StoryVersion != 0 && tokenParams.StoryVersion != -1) { CharismaLogger.Log($"Generating playthrough token with version {tokenParams.StoryVersion} of the story"); } request.AddHeader("Content-Type", "application/json"); request.Send(); }
/// <summary> /// Connect to Charisma /// </summary> /// <param name="onReadyCallback">Called when successfully connected to Charisma.</param> public void Connect(Action onReadyCallback) { if (IsConnected) { return; } var options = new SocketOptions { ConnectWith = TransportTypes.WebSocket, AdditionalQueryParams = new ObservableDictionary <string, string> { { "token", Token } } }; _socketManager = new SocketManager(new Uri($"{BaseUrl}/socket.io/"), options) { Encoder = new LitJsonEncoder() }; _socket = _socketManager.GetSocket("/play"); _socket.On(SocketIOEventTypes.Connect, (socket, packet, args) => { CharismaLogger.Log("Connected to socket"); }); _socket.On("error", (socket, packet, args) => { Debug.LogError(args[0].ToString()); }); _socket.On("status", (socket, packet, args) => { if ((string)args[0] == "ready") { CharismaLogger.Log("Ready to begin play"); IsReadyToPlay = true; onReadyCallback?.Invoke(); } else { Debug.LogError("Charisma: Failed to set up websocket connection to server"); } }); _socket.On("message", (socket, packet, args) => { CharismaLogger.Log("Event received: `message`"); MainThreadConsumer.Instance.Enqueue((async() => { // Remove the `['message', ` at the front and the `]` at the back. var modifiedString = packet.Payload.Remove(packet.Payload.Length - 1, 1).Remove(0, 11); var deserialized = await Task.Run(() => JsonConvert.DeserializeObject <Events.MessageEvent>(modifiedString)); OnMessage?.Invoke(deserialized.ConversationId, deserialized); })); }); _socket.On("start-typing", (socket, packet, args) => { CharismaLogger.Log("Event received: `start-typing`"); var deserialized = JsonConvert.DeserializeObject <Conversation>(packet.Payload); OnStartTyping?.Invoke(deserialized.ConversationId); }); _socket.On("stop-typing", (socket, packet, args) => { CharismaLogger.Log("Event received: `stop-typing`"); var deserialized = JsonConvert.DeserializeObject <Conversation>(packet.Payload); OnStopTyping?.Invoke(deserialized.ConversationId); }); _socket.On("problem", (socket, packet, args) => { CharismaLogger.Log("Event received: `problem`"); var deserialized = JsonConvert.DeserializeObject <CharismaError>(packet.Payload); CharismaLogger.Log(deserialized.Error); }); }