diff --git a/CSharp/demo-RollerSkill/App_Start/WebApiConfig.cs b/CSharp/demo-RollerSkill/App_Start/WebApiConfig.cs new file mode 100644 index 0000000000..7ba0c607f6 --- /dev/null +++ b/CSharp/demo-RollerSkill/App_Start/WebApiConfig.cs @@ -0,0 +1,33 @@ +namespace RollerSkillBot +{ + using System.Web.Http; + using Newtonsoft.Json; + using Newtonsoft.Json.Serialization; + + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + // Json settings + config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; + config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); + config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; + JsonConvert.DefaultSettings = () => new JsonSerializerSettings() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + Formatting = Newtonsoft.Json.Formatting.Indented, + NullValueHandling = NullValueHandling.Ignore, + }; + + // Web API configuration and services + + // Web API routes + config.MapHttpAttributeRoutes(); + + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional }); + } + } +} diff --git a/CSharp/demo-RollerSkill/Controllers/MessagesController.cs b/CSharp/demo-RollerSkill/Controllers/MessagesController.cs new file mode 100644 index 0000000000..d85ce651e4 --- /dev/null +++ b/CSharp/demo-RollerSkill/Controllers/MessagesController.cs @@ -0,0 +1,27 @@ +namespace RollerSkillBot +{ + using System.Net; + using System.Net.Http; + using System.Threading.Tasks; + using System.Web.Http; + using Microsoft.Bot.Builder.Dialogs; + using Microsoft.Bot.Connector; + using RollerSkillBot.Dialogs; + + [BotAuthentication] + public class MessagesController : ApiController + { + /// + /// POST: api/Messages + /// Receive a message from a user and reply to it + /// + public async Task Post([FromBody]Activity activity) + { + await Conversation.SendAsync(activity, () => new RootDispatchDialog()); + + var response = Request.CreateResponse(HttpStatusCode.OK); + + return response; + } + } +} \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Dialogs/CreateGameDialog.cs b/CSharp/demo-RollerSkill/Dialogs/CreateGameDialog.cs new file mode 100644 index 0000000000..27be538a2d --- /dev/null +++ b/CSharp/demo-RollerSkill/Dialogs/CreateGameDialog.cs @@ -0,0 +1,70 @@ +namespace RollerSkillBot.Dialogs +{ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + using Microsoft.Bot.Builder.Dialogs; + using RollerSkillBot.Properties; + + [Serializable] + public class CreateGameDialog : IDialog + { + public async Task StartAsync(IDialogContext context) + { + context.UserData.SetValue(Utils.GameDataKey, new GameData()); + + var descriptions = new List() { "4 Sides", "6 Sides", "8 Sides", "10 Sides", "12 Sides", "20 Sides" }; + var choices = new Dictionary>() + { + { "4", new List { "four", "for", "4 sided", "4 sides" } }, + { "6", new List { "six", "sex", "6 sided", "6 sides" } }, + { "8", new List { "eight", "8 sided", "8 sides" } }, + { "10", new List { "ten", "10 sided", "10 sides" } }, + { "12", new List { "twelve", "12 sided", "12 sides" } }, + { "20", new List { "twenty", "20 sided", "20 sides" } } + }; + + var promptOptions = new PromptOptionsWithSynonyms( + Resources.ChooseSides, + choices: choices, + descriptions: descriptions, + speak: SSMLHelper.Speak(Utils.RandomPick(Resources.ChooseSidesSSML))); + + PromptDialog.Choice(context, this.DiceChoiceReceivedAsync, promptOptions); + } + + private async Task DiceChoiceReceivedAsync(IDialogContext context, IAwaitable result) + { + GameData game; + if (context.UserData.TryGetValue(Utils.GameDataKey, out game)) + { + int sides; + if (int.TryParse(await result, out sides)) + { + game.Sides = sides; + context.UserData.SetValue(Utils.GameDataKey, game); + } + + var promptText = string.Format(Resources.ChooseCount, sides); + + // TODO: When supported, update to pass Min and Max paramters + var promptOption = new PromptOptions(promptText, speak: SSMLHelper.Speak(Utils.RandomPick(Resources.ChooseCountSSML))); + + var prompt = new PromptDialog.PromptInt64(promptOption, min: 1, max: 100); + context.Call(prompt, this.DiceNumberReceivedAsync); + } + } + + private async Task DiceNumberReceivedAsync(IDialogContext context, IAwaitable result) + { + GameData game; + if (context.UserData.TryGetValue(Utils.GameDataKey, out game)) + { + game.Count = await result; + context.UserData.SetValue(Utils.GameDataKey, game); + } + + context.Done(game); + } + } +} \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Dialogs/HelpDialog.cs b/CSharp/demo-RollerSkill/Dialogs/HelpDialog.cs new file mode 100644 index 0000000000..54373e2429 --- /dev/null +++ b/CSharp/demo-RollerSkill/Dialogs/HelpDialog.cs @@ -0,0 +1,40 @@ +namespace RollerSkillBot.Dialogs +{ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + using Microsoft.Bot.Builder.Dialogs; + using Microsoft.Bot.Connector; + using RollerSkillBot.Properties; + + [Serializable] + public class HelpDialog : IDialog + { + private const string RollDiceOptionValue = "roll some dice"; + + private const string PlayCrapsOptionValue = "play craps"; + + public async Task StartAsync(IDialogContext context) + { + var message = context.MakeMessage(); + message.Speak = SSMLHelper.Speak(Resources.HelpSSML); + message.InputHint = InputHints.AcceptingInput; + + message.Attachments = new List + { + new HeroCard(Resources.HelpTitle) + { + Buttons = new List + { + new CardAction(ActionTypes.ImBack, "Roll Dice", value: RollDiceOptionValue), + new CardAction(ActionTypes.ImBack, "Play Craps", value: PlayCrapsOptionValue) + } + }.ToAttachment() + }; + + await context.PostAsync(message); + + context.Done(null); + } + } +} \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Dialogs/PlayGameDialog.cs b/CSharp/demo-RollerSkill/Dialogs/PlayGameDialog.cs new file mode 100644 index 0000000000..96f1a5483c --- /dev/null +++ b/CSharp/demo-RollerSkill/Dialogs/PlayGameDialog.cs @@ -0,0 +1,147 @@ +namespace RollerSkillBot.Dialogs +{ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + using Microsoft.Bot.Builder.Dialogs; + using Microsoft.Bot.Connector; + using RollerSkillBot.Properties; + + [Serializable] + public class PlayGameDialog : IDialog + { + private const string RollAgainOptionValue = "roll again"; + + private const string NewGameOptionValue = "new game"; + + private GameData gameData; + + public PlayGameDialog(GameData gameData) + { + this.gameData = gameData; + } + + public async Task StartAsync(IDialogContext context) + { + if (this.gameData == null) + { + if (!context.UserData.TryGetValue(Utils.GameDataKey, out this.gameData)) + { + // User started session with "roll again" so let's just send them to + // the 'CreateGameDialog' + context.Done(null); + } + } + + int total = 0; + var randomGenerator = new Random(); + var rolls = new List(); + + // Generate Rolls + for (int i = 0; i < this.gameData.Count; i++) + { + var roll = randomGenerator.Next(1, this.gameData.Sides); + total += roll; + rolls.Add(roll); + } + + // Format rolls results + var result = string.Join(" . ", rolls.ToArray()); + bool multiLine = rolls.Count > 5; + + var card = new HeroCard() + { + Subtitle = string.Format( + this.gameData.Count > 1 ? Resources.CardSubtitlePlural : Resources.CardSubtitleSingular, + this.gameData.Count, + this.gameData.Sides), + Buttons = new List() + { + new CardAction(ActionTypes.ImBack, "Roll Again", value: RollAgainOptionValue), + new CardAction(ActionTypes.ImBack, "New Game", value: NewGameOptionValue) + } + }; + + if (multiLine) + { + card.Text = result; + } + else + { + card.Title = result; + } + + var message = context.MakeMessage(); + message.Attachments = new List() + { + card.ToAttachment() + }; + + // Determine bots reaction for speech purposes + string reaction = "normal"; + + var min = this.gameData.Count; + var max = this.gameData.Count * this.gameData.Sides; + var score = total / max; + if (score == 1) + { + reaction = "Best"; + } + else if (score == 0) + { + reaction = "Worst"; + } + else if (score <= 0.3) + { + reaction = "Bad"; + } + else if (score >= 0.8) + { + reaction = "Good"; + } + + // Check for special craps rolls + if (this.gameData.Type == "Craps") + { + switch (total) + { + case 2: + case 3: + case 12: + reaction = "CrapsLose"; + break; + case 7: + reaction = "CrapsSeven"; + break; + case 11: + reaction = "CrapsEleven"; + break; + default: + reaction = "CrapsRetry"; + break; + } + } + + // Build up spoken response + var spoken = string.Empty; + if (this.gameData.Turns == 0) + { + spoken += Utils.RandomPick(Resources.ResourceManager.GetString($"Start{this.gameData.Type}GameSSML")); + } + + spoken += Utils.RandomPick(Resources.ResourceManager.GetString($"{reaction}RollReactionSSML")); + + message.Speak = SSMLHelper.Speak(spoken); + + // Increment number of turns and store game to roll again + this.gameData.Turns++; + context.UserData.SetValue(Utils.GameDataKey, this.gameData); + + // Send card and bots reaction to user. + message.InputHint = InputHints.AcceptingInput; + await context.PostAsync(message); + + context.Done(null); + } + } +} \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Dialogs/RootDispatchDialog.cs b/CSharp/demo-RollerSkill/Dialogs/RootDispatchDialog.cs new file mode 100644 index 0000000000..8759b8a403 --- /dev/null +++ b/CSharp/demo-RollerSkill/Dialogs/RootDispatchDialog.cs @@ -0,0 +1,87 @@ +namespace RollerSkillBot.Dialogs +{ + using System; + using System.Threading.Tasks; + using Microsoft.Bot.Builder.Dialogs; + using Microsoft.Bot.Builder.Scorables; + using Microsoft.Bot.Connector; + + [Serializable] + public class RootDispatchDialog : DispatchDialog + { + // generic activity handler. + [MethodBind] + [ScorableGroup(0)] + public async Task ActivityHandler(IDialogContext context, IActivity activity) + { + switch (activity.Type) + { + case ActivityTypes.Message: + this.ContinueWithNextGroup(); + break; + + case ActivityTypes.ConversationUpdate: + case ActivityTypes.ContactRelationUpdate: + case ActivityTypes.Typing: + case ActivityTypes.DeleteUserData: + case ActivityTypes.Ping: + default: + break; + } + } + + [RegexPattern("(roll|role|throw|shoot).*(dice|die|dye|bones)")] + [RegexPattern("new game")] + [ScorableGroup(1)] + public async Task NewGame(IDialogContext context, IActivity activity) + { + context.Call(new CreateGameDialog(), AfterGameCreated); + } + + [RegexPattern("(roll|role|throw|shoot) again")] + [ScorableGroup(1)] + public async Task RollAgain(IDialogContext context, IActivity activity) + { + await PlayGame(context); + } + + [RegexPattern("(play|start).*(craps)")] + [ScorableGroup(1)] + public async Task PlayCraps(IDialogContext context, IActivity activity) + { + var crapsGame = new GameData("Craps", 6, 2, 0); + await PlayGame(context, crapsGame); + } + + [RegexPattern("help")] + [ScorableGroup(1)] + public async Task Help(IDialogContext context, IActivity activity) + { + await this.Default(context, activity); + } + + [MethodBind] + [ScorableGroup(2)] + public async Task Default(IDialogContext context, IActivity activity) + { + context.Call(new HelpDialog(), AfterDialog); + } + + private static async Task PlayGame(IDialogContext context, GameData gameData = null) + { + context.Call(new PlayGameDialog(gameData), AfterDialog); + } + + private static async Task AfterGameCreated(IDialogContext context, IAwaitable result) + { + var game = await result; + + await PlayGame(context, game); + } + + private static async Task AfterDialog(IDialogContext context, IAwaitable result) + { + context.Done(null); + } + } +} \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Global.asax b/CSharp/demo-RollerSkill/Global.asax new file mode 100644 index 0000000000..ce6e96f1e9 --- /dev/null +++ b/CSharp/demo-RollerSkill/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="RollerSkillBot.WebApiApplication" Language="C#" %> \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Global.asax.cs b/CSharp/demo-RollerSkill/Global.asax.cs new file mode 100644 index 0000000000..d8d062d665 --- /dev/null +++ b/CSharp/demo-RollerSkill/Global.asax.cs @@ -0,0 +1,12 @@ +namespace RollerSkillBot +{ + using System.Web.Http; + + public class WebApiApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + GlobalConfiguration.Configure(WebApiConfig.Register); + } + } +} diff --git a/CSharp/demo-RollerSkill/Models/GameData.cs b/CSharp/demo-RollerSkill/Models/GameData.cs new file mode 100644 index 0000000000..a33f41a392 --- /dev/null +++ b/CSharp/demo-RollerSkill/Models/GameData.cs @@ -0,0 +1,29 @@ +namespace RollerSkillBot +{ + using System; + + [Serializable] + public class GameData + { + public GameData() + { + this.Type = "Custom"; + } + + public GameData(string type, int sides, long count, int turns) + { + this.Type = type; + this.Sides = sides; + this.Count = count; + this.Turns = turns; + } + + public string Type { get; set; } + + public int Sides { get; set; } + + public long Count { get; set; } + + public int Turns { get; set; } + } +} \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Properties/AssemblyInfo.cs b/CSharp/demo-RollerSkill/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..9392851439 --- /dev/null +++ b/CSharp/demo-RollerSkill/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RollerSkillBot")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RollerSkillBot")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a8ba1066-5695-4d71-abb4-65e5a5e0c3d4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CSharp/demo-RollerSkill/Properties/Resources.Designer.cs b/CSharp/demo-RollerSkill/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..3d57c05e0c --- /dev/null +++ b/CSharp/demo-RollerSkill/Properties/Resources.Designer.cs @@ -0,0 +1,234 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace RollerSkillBot.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RollerSkillBot.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to ouch|I hope your luck improves.|I think I saw that coming.|That's not good.. + /// + internal static string BadRollReactionSSML { + get { + return ResourceManager.GetString("BadRollReactionSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to That was a perfect roll!|Awesome!|You can't get better than that.. + /// + internal static string BestRollReactionSSML { + get { + return ResourceManager.GetString("BestRollReactionSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to rolled {0} dice using a {1}-sided dice. + /// + internal static string CardSubtitlePlural { + get { + return ResourceManager.GetString("CardSubtitlePlural", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to using a {1}-sided dice. + /// + internal static string CardSubtitleSingular { + get { + return ResourceManager.GetString("CardSubtitleSingular", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How many {0} sided dice should I roll?. + /// + internal static string ChooseCount { + get { + return ResourceManager.GetString("ChooseCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How many dice? Choose a number from 1 to a hundred.|How many dice? The more the merrier|How many dice?. + /// + internal static string ChooseCountSSML { + get { + return ResourceManager.GetString("ChooseCountSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Number of Sides. + /// + internal static string ChooseSides { + get { + return ResourceManager.GetString("ChooseSides", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How many sides on the dice?|Pick your poison.|All the standard sizes are supported.. + /// + internal static string ChooseSidesSSML { + get { + return ResourceManager.GetString("ChooseSidesSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Nice, an eleven you win!. + /// + internal static string CrapsElevenRollReactionSSML { + get { + return ResourceManager.GetString("CrapsElevenRollReactionSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You crapped out.|Oh no you lost.. + /// + internal static string CrapsLoseRollReactionSSML { + get { + return ResourceManager.GetString("CrapsLoseRollReactionSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Roll again.|Try again you want a seven or eleven.|Roll again and try not to get a 2, 3, or 12.. + /// + internal static string CrapsRetryRollReactionSSML { + get { + return ResourceManager.GetString("CrapsRetryRollReactionSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You win with a lucky seven!. + /// + internal static string CrapsSevenRollReactionSSML { + get { + return ResourceManager.GetString("CrapsSevenRollReactionSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to That's pretty good.|There you go.|That should help.. + /// + internal static string GoodRollReactionSSML { + get { + return ResourceManager.GetString("GoodRollReactionSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to I'm roller, the dice rolling bot. You can say 'roll some dice' or play one of the games I know how to play.. + /// + internal static string HelpSSML { + get { + return ResourceManager.GetString("HelpSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Roller Options. + /// + internal static string HelpTitle { + get { + return ResourceManager.GetString("HelpTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to That's not too bad|It could have been worse.|That was a decent roll.. + /// + internal static string NormalRollReactionSSML { + get { + return ResourceManager.GetString("NormalRollReactionSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to I love vegas.|Good luck.. + /// + internal static string StartCrapsGameSSML { + get { + return ResourceManager.GetString("StartCrapsGameSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lets do this!|Here we go.|Are you ready for this?. + /// + internal static string StartCustomGameSSML { + get { + return ResourceManager.GetString("StartCustomGameSSML", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to wow... just wow...|oh no. That was horrible.| You can't do better. Oh wait you can.. + /// + internal static string WorstRollReactionSSML { + get { + return ResourceManager.GetString("WorstRollReactionSSML", resourceCulture); + } + } + } +} diff --git a/CSharp/demo-RollerSkill/Properties/Resources.resx b/CSharp/demo-RollerSkill/Properties/Resources.resx new file mode 100644 index 0000000000..de79251e90 --- /dev/null +++ b/CSharp/demo-RollerSkill/Properties/Resources.resx @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ouch|I hope your luck improves.|I think I saw that coming.|That's not good. + + + That was a perfect roll!|Awesome!|You can't get better than that. + + + rolled {0} dice using a {1}-sided dice + + + using a {1}-sided dice + + + How many {0} sided dice should I roll? + + + How many dice? Choose a number from 1 to a hundred.|How many dice? The more the merrier|How many dice? + + + Number of Sides + + + How many sides on the dice?|Pick your poison.|All the standard sizes are supported. + + + Nice, an eleven you win! + + + You crapped out.|Oh no you lost. + + + Roll again.|Try again you want a seven or eleven.|Roll again and try not to get a 2, 3, or 12. + + + You win with a lucky seven! + + + That's pretty good.|There you go.|That should help. + + + I'm roller, the dice rolling bot. You can say 'roll some dice' or play one of the games I know how to play. + + + Roller Options + + + That's not too bad|It could have been worse.|That was a decent roll. + + + I love vegas.|Good luck. + + + Lets do this!|Here we go.|Are you ready for this? + + + wow... just wow...|oh no. That was horrible.| You can't do better. Oh wait you can. + + \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/RollerSkill.sln b/CSharp/demo-RollerSkill/RollerSkill.sln new file mode 100644 index 0000000000..2c0d6714b8 --- /dev/null +++ b/CSharp/demo-RollerSkill/RollerSkill.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.4 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RollerSkillBot", "RollerSkillBot.csproj", "{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/CSharp/demo-RollerSkill/RollerSkillBot.csproj b/CSharp/demo-RollerSkill/RollerSkillBot.csproj new file mode 100644 index 0000000000..6a4d938dde --- /dev/null +++ b/CSharp/demo-RollerSkill/RollerSkillBot.csproj @@ -0,0 +1,182 @@ + + + + + Debug + AnyCPU + + + 2.0 + {A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + RollerSkillBot + RollerSkillBot + v4.6 + true + + + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + packages\Autofac.3.5.2\lib\net40\Autofac.dll + + + packages\Chronic.Signed.0.3.2\lib\net40\Chronic.dll + + + packages\Microsoft.Bot.Builder.3.8.0.0\lib\net46\Microsoft.Bot.Builder.dll + + + packages\Microsoft.Bot.Builder.3.8.0.0\lib\net46\Microsoft.Bot.Builder.Autofac.dll + + + packages\Microsoft.Bot.Builder.3.8.0.0\lib\net46\Microsoft.Bot.Connector.dll + + + + packages\Microsoft.IdentityModel.Protocol.Extensions.1.0.4.403061554\lib\net45\Microsoft.IdentityModel.Protocol.Extensions.dll + + + packages\Microsoft.Rest.ClientRuntime.2.3.2\lib\net45\Microsoft.Rest.ClientRuntime.dll + + + packages\Microsoft.WindowsAzure.ConfigurationManager.3.1.0\lib\net40\Microsoft.WindowsAzure.Configuration.dll + + + packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll + + + + packages\System.IdentityModel.Tokens.Jwt.4.0.4.403061554\lib\net45\System.IdentityModel.Tokens.Jwt.dll + + + + + packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll + + + + + + + + + + + + + + packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll + + + packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll + + + + + + + + + + + + Designer + + + + + + + + + + + Global.asax + + + + + True + True + Resources.resx + + + + + + + + Web.config + + + Web.config + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + true + + + + + + + + + True + True + 3979 + / + http://localhost:3979/ + False + False + + + False + + + + + + \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/SSMLHelper.cs b/CSharp/demo-RollerSkill/SSMLHelper.cs new file mode 100644 index 0000000000..ceab44f287 --- /dev/null +++ b/CSharp/demo-RollerSkill/SSMLHelper.cs @@ -0,0 +1,34 @@ +namespace RollerSkillBot +{ + using System.Xml.Linq; + + public static class SSMLHelper + { + public static string Speak(string text) + { + var ssml = new XDocument(new XElement( + "speak", + new XAttribute("version", "1.0"), + new XAttribute(XNamespace.Xml + "lang", "en-US"), + text)); + + return ssml.ToString(); + } + + public static string Emphasis(string text) + { + var ssml = new XElement("emphasis", text); + return ssml.ToString(); + } + + public static string SayAs(string interpretAs, string text) + { + var ssml = new XElement( + "say-as", + new XAttribute("interpret-as", interpretAs), + text); + + return ssml.ToString(); + } + } +} \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Utils.cs b/CSharp/demo-RollerSkill/Utils.cs new file mode 100644 index 0000000000..9f05b3e55a --- /dev/null +++ b/CSharp/demo-RollerSkill/Utils.cs @@ -0,0 +1,16 @@ +namespace RollerSkillBot +{ + using System; + + public static class Utils + { + public const string GameDataKey = "GameData"; + + public static string RandomPick(string listText) + { + var list = listText.Split('|'); + var random = new Random(); + return list[random.Next(list.Length)]; + } + } +} \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Web.Debug.config b/CSharp/demo-RollerSkill/Web.Debug.config new file mode 100644 index 0000000000..2e302f9f95 --- /dev/null +++ b/CSharp/demo-RollerSkill/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Web.Release.config b/CSharp/demo-RollerSkill/Web.Release.config new file mode 100644 index 0000000000..c35844462b --- /dev/null +++ b/CSharp/demo-RollerSkill/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/Web.config b/CSharp/demo-RollerSkill/Web.config new file mode 100644 index 0000000000..05b292cffe --- /dev/null +++ b/CSharp/demo-RollerSkill/Web.config @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CSharp/demo-RollerSkill/default.htm b/CSharp/demo-RollerSkill/default.htm new file mode 100644 index 0000000000..52c7dabf1f --- /dev/null +++ b/CSharp/demo-RollerSkill/default.htm @@ -0,0 +1,12 @@ + + + + + + + +

RollerSkillBot

+

A simple dice rolling skill/bot that's been optimized for speech enabled channels.

+

Visit Bot Framework to register your bot. When you register it, remember to set your bot's endpoint to

https://your_bots_hostname/api/messages

+ + diff --git a/CSharp/demo-RollerSkill/packages.config b/CSharp/demo-RollerSkill/packages.config new file mode 100644 index 0000000000..0648596f79 --- /dev/null +++ b/CSharp/demo-RollerSkill/packages.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file