Beispiel #1
0
        private async Task <AdventureState> RestoreAdventureState(Adventure adventure, Session session)
        {
            AdventureState state = null;

            // attempt to deserialize the player information
            if (session.New)
            {
                LogInfo("new session started");
            }
            else if (!session.Attributes.TryGetValue(SESSION_STATE_KEY, out object playerStateValue) || !(playerStateValue is JObject playerState))
            {
                LogWarn($"unable to find player state in session (type: {playerStateValue?.GetType().Name})\n" + JsonConvert.SerializeObject(session));
            }
            else
            {
                state = playerState.ToObject <AdventureState>();

                // validate the adventure still has a matching place for the player
                if (!adventure.Places.ContainsKey(state.CurrentPlaceId))
                {
                    LogWarn($"unable to find matching place for restored player in session (value: '{state.CurrentPlaceId}')\n" + JsonConvert.SerializeObject(session));

                    // reset player
                    state.Reset(Adventure.StartPlaceId);
                }
            }

            // create new player if no player was restored
            if (state == null)
            {
                LogInfo("new player session started");
                state = new AdventureState(Adventure.StartPlaceId);
            }
            return(state);
        }
Beispiel #2
0
        private async Task StoreAdventureState(AdventureState state)
        {
            if (_adventurePlayerTable != null)
            {
                var jsonState = JsonConvert.SerializeObject(state, Formatting.None);
                LogInfo($"storing state in player table\n{jsonState}");
                await _dynamoClient.PutItemAsync(_adventurePlayerTable, new Dictionary <string, AttributeValue> {
                    ["PlayerId"] = new AttributeValue {
                        S = state.RecordId
                    },
                    ["State"] = new AttributeValue {
                        S = jsonState
                    },
                    ["Expire"] = new AttributeValue {
                        N = ToEpoch(DateTime.UtcNow.AddDays(30)).ToString()
                    }
                });
            }

            // local functions
            uint ToEpoch(DateTime date)
            {
                return((uint)date.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);
            }
        }
Beispiel #3
0
        //--- Class Methods ---
        public static void Main(string[] args)
        {
            var app = new CommandLineApplication {
                Name        = "AdventureBot.Cli",
                FullName    = "AdventureBot Command Line Interface",
                Description = "Choose-Your-Adventure CLI"
            };

            app.HelpOption();
            var filenameArg = app.Argument("<FILENAME>", "path to adventure file");

            app.OnExecute(() => {
                if (filenameArg.Value == null)
                {
                    Console.WriteLine(app.GetHelpText());
                    return;
                }
                if (!File.Exists(filenameArg.Value))
                {
                    app.ShowRootCommandFullNameAndVersion();
                    Console.WriteLine("ERROR: could not find file");
                    return;
                }

                // initialize the adventure from the adventure file
                Adventure adventure;
                try {
                    adventure = Adventure.LoadFrom(filenameArg.Value);
                } catch (AdventureException e) {
                    Console.WriteLine($"ERROR: {e.Message}");
                    return;
                } catch (Exception e) {
                    Console.WriteLine($"ERROR: unable to load file");
                    Console.WriteLine(e);
                    return;
                }

                // invoke adventure
                var state  = new AdventureState("cli", Adventure.StartPlaceId);
                var engine = new AdventureEngine(adventure, state);
                AdventureLoop(engine);
            });
            app.Execute(args);
        }
Beispiel #4
0
 public Adventure()
 {
     AdventureState = AdventureState.CREATION;
 }
Beispiel #5
0
 private async Task StoreAdventureState(AdventureState state)
 {
 }
Beispiel #6
0
        private async Task <AdventureState> RestoreAdventureState(Adventure adventure, Session session)
        {
            var            recordId = UserIdToSessionRecordKey(session.User.UserId);
            AdventureState state    = null;

            if (session.New)
            {
                // check if the adventure state can be restored from the player table
                if (_adventurePlayerTable != null)
                {
                    // check if a session can be restored from the database
                    var record = await _dynamoClient.GetItemAsync(_adventurePlayerTable, new Dictionary <string, AttributeValue> {
                        ["PlayerId"] = new AttributeValue {
                            S = recordId
                        }
                    });

                    if (record.IsItemSet)
                    {
                        state = JsonConvert.DeserializeObject <AdventureState>(record.Item["State"].S);
                        LogInfo($"restored state from player table\n{record.Item["State"].S}");

                        // check if the place the player was in still exists or if the player had reached an end state
                        if (!adventure.Places.TryGetValue(state.CurrentPlaceId, out AdventurePlace place))
                        {
                            LogWarn($"unable to find matching place for restored state from player table (value: '{state.CurrentPlaceId}')");

                            // reset player
                            state.Reset(Adventure.StartPlaceId);
                        }
                        else if (place.Finished)
                        {
                            LogInfo("restored player had reached end place");

                            // reset player
                            state.Reset(Adventure.StartPlaceId);
                        }
                        else if (state.CurrentPlaceId == Adventure.StartPlaceId)
                        {
                            // reset player
                            state.Reset(Adventure.StartPlaceId);
                        }
                    }
                    else
                    {
                        LogInfo("no previous state found in player table");
                    }
                }
            }
            else
            {
                // attempt to deserialize the player information
                if (!session.Attributes.TryGetValue(SESSION_STATE_KEY, out object playerStateValue) || !(playerStateValue is JObject playerState))
                {
                    LogWarn($"unable to find player state in session (type: {playerStateValue?.GetType().Name})\n" + JsonConvert.SerializeObject(session));
                }
                else
                {
                    state = playerState.ToObject <AdventureState>();

                    // validate the adventure still has a matching place for the player
                    if (!adventure.Places.ContainsKey(state.CurrentPlaceId))
                    {
                        LogWarn($"unable to find matching place for restored player in session (value: '{state.CurrentPlaceId}')\n" + JsonConvert.SerializeObject(session));

                        // reset player
                        state.Reset(Adventure.StartPlaceId);
                    }
                }
            }

            // create new player if no player was restored
            if (state == null)
            {
                LogInfo("new player session started");
                state = new AdventureState(recordId, Adventure.StartPlaceId);
            }
            return(state);

            // local functions
            string UserIdToSessionRecordKey(string userId)
            {
                var md5 = System.Security.Cryptography.MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(userId));

                return($"resume-{new Guid(md5):N}");
            }
        }