private static Result <Position> ParsePositionField(ref PlayerLexer lexer) { Token next; Result <long> longValue; if (!MultiValueVerification(ref lexer, Tokens.Position)) { return(Result <Position> .Error()); } if ((next = lexer.NextToken()).Type != Tokens.Number) { return(Result <Position> .Error()); } var x = next.Number; if (!(longValue = NextNumberValue(ref lexer)).Success) { return(Result <Position> .Error()); } var y = longValue.Value; if (!(longValue = NextNumberValue(ref lexer)).Success) { return(Result <Position> .Error()); } var z = longValue.Value; if (lexer.NextToken().Type != Tokens.RightParenthesis) { return(Result <Position> .Error()); } return(Result <Position> .Ok(new Position((ushort)x, (ushort)y, (byte)z))); }
private static Result <EquipmentBuilder> ParseEquipmentField(ref PlayerLexer lexer) { Token next; if (lexer.NextToken().Type != Tokens.Equals) { return(Result <EquipmentBuilder> .Error()); } if (lexer.NextToken().Type != Tokens.LeftBracket) { return(Result <EquipmentBuilder> .Error()); } var builder = new EquipmentBuilder(); while ((next = lexer.NextToken()).Type != Tokens.RightBracket && next.Type != Tokens.Eof && next.Type != Tokens.None && next.Type != Tokens.Unknown) { if (!ParseEquipmentPiece(ref lexer, builder, next)) { return(Result <EquipmentBuilder> .Error()); } } if (next.Type != Tokens.RightBracket) { return(Result <EquipmentBuilder> .Error()); } return(Result <EquipmentBuilder> .Ok(builder)); }
private static Result <List <Item> > ParseInventoryField(ref PlayerLexer lexer) { Token next; if (lexer.NextToken().Type != Tokens.Equals) { return(Result <List <Item> > .Error()); } if (lexer.NextToken().Type != Tokens.LeftBracket) { return(Result <List <Item> > .Error()); } var items = new List <Item>(); while ((next = lexer.NextToken()).Type != Tokens.RightBracket && next.Type != Tokens.Eof && next.Type != Tokens.None && next.Type != Tokens.Unknown) { switch (next.Type) { case Tokens.Item: var item = ParseItemValue(ref lexer); if (!item.Success) { return(Result <List <Item> > .Error()); } items.Add(item.Value); break; case Tokens.Container: var container = ParseItemValue(ref lexer); if (!container.Success) { return(Result <List <Item> > .Error()); } if (!ParseContainer(ref lexer, container.Value)) { return(Result <List <Item> > .Error()); } items.Add(container.Value); break; default: return(Result <List <Item> > .Error()); } } if (next.Type != Tokens.RightBracket) { return(Result <List <Item> > .Error()); } return(Result <List <Item> > .Ok(items)); }
private static Result <Outfit> ParseOutfitField(ref PlayerLexer lexer) { if (!MultiValueVerification(ref lexer, Tokens.Outfit)) { return(Result <Outfit> .Error()); } Token next; if ((next = lexer.NextToken()).Type != Tokens.String) { return(Result <Outfit> .Error()); } var name = next.StringText; if (!Enum.TryParse <Outfits>(name, true, out var outfit)) { return(Result <Outfit> .Error()); } Result <long> longValue; if (!(longValue = NextNumberValue(ref lexer)).Success) { return(Result <Outfit> .Error()); } var head = longValue.Value; if (!(longValue = NextNumberValue(ref lexer)).Success) { return(Result <Outfit> .Error()); } var body = longValue.Value; if (!(longValue = NextNumberValue(ref lexer)).Success) { return(Result <Outfit> .Error()); } var legs = longValue.Value; if (!(longValue = NextNumberValue(ref lexer)).Success) { return(Result <Outfit> .Error()); } var feet = longValue.Value; if (lexer.NextToken().Type != Tokens.RightParenthesis) { return(Result <Outfit> .Error()); } return(Result <Outfit> .Ok(new Outfit(outfit, (byte)head, (byte)body, (byte)legs, (byte)feet))); }
private static Result <string> ParseStringField(ref PlayerLexer lexer) { Token next; if (lexer.NextToken().Type != Tokens.Equals) { return(Result <string> .Error()); } if ((next = lexer.NextToken()).Type != Tokens.String) { return(Result <string> .Error()); } return(Result <string> .Ok(next.StringText)); }
private static Result <long> ParseNumberField(ref PlayerLexer lexer) { Token next; if (lexer.NextToken().Type != Tokens.Equals) { return(Result <long> .Error()); } if ((next = lexer.NextToken()).Type != Tokens.Number) { return(Result <long> .Error()); } return(Result <long> .Ok(next.Number)); }
private static bool MultiValueVerification(ref PlayerLexer lexer, Tokens valueType) { if (lexer.NextToken().Type != Tokens.Equals) { return(false); } if (lexer.NextToken().Type != valueType) { return(false); } return(lexer.NextToken().Type == Tokens.LeftParenthesis); }
private static Result <long> NextNumberValue(ref PlayerLexer lexer) { Token next; if (lexer.NextToken().Type != Tokens.Comma) { return(Result <long> .Error()); } if ((next = lexer.NextToken()).Type != Tokens.Number) { return(Result <long> .Error()); } return(Result <long> .Ok(next.Number)); }
private static bool ParseContainer(ref PlayerLexer lexer, Item parent) { Token next; if (lexer.NextToken().Type != Tokens.Equals) { return(false); } if (lexer.NextToken().Type != Tokens.LeftBrace) { return(false); } while ((next = lexer.NextToken()).Type != Tokens.RightBrace && next.Type != Tokens.Eof && next.Type != Tokens.None && next.Type != Tokens.Unknown) { switch (next.Type) { case Tokens.Item: var item = ParseItemValue(ref lexer); if (!item.Success) { return(false); } parent.AddInside(item.Value); break; case Tokens.Container: var container = ParseItemValue(ref lexer); if (!container.Success) { return(false); } ParseContainer(ref lexer, container.Value); parent.AddInside(container.Value); break; default: return(false); } } if (next.Type != Tokens.RightBrace) { return(false); } return(true); }
private static Result <bool> ParseBoolField(ref PlayerLexer lexer) { Token next; if (lexer.NextToken().Type != Tokens.Equals) { return(Result <bool> .Error()); } if ((next = lexer.NextToken()).Type == Tokens.True) { return(Result <bool> .Ok(true)); } if (next.Type == Tokens.False) { return(Result <bool> .Ok(false)); } return(Result <bool> .Error()); }
private static Result <Item> ParseItemValue(ref PlayerLexer lex) { if (lex.NextToken().Type != Tokens.LeftParenthesis) { return(Result <Item> .Error()); } var value = lex.NextToken(); if (value.Type != Tokens.Number) { return(Result <Item> .Error()); } var next = lex.NextToken(); if (next.Type == Tokens.RightParenthesis) // 1 arg { return(Result <Item> .Ok(IoC.Items.Create((ushort)value.Number))); } // 2 args if (next.Type != Tokens.Comma) { return(Result <Item> .Error()); } var extra = lex.NextToken(); if (extra.Type != Tokens.Number) { return(Result <Item> .Error()); } if (lex.NextToken().Type != Tokens.RightParenthesis) { return(Result <Item> .Error()); } return(Result <Item> .Ok(IoC.Items.Create((ushort)value.Number, (byte)extra.Number))); }
public Player Read(string path) { var fileName = Path.GetFileName(path); var read = File.ReadAllText(path); var player = new CharacterBuilder(); var lexer = new PlayerLexer(read.AsSpan()); Token lastToken = Token.None; Token token; Result <bool> boolField; Result <long> numberField; Result <string> stringField; Result <Position> posField; Result <Outfit> outfitField; Result <EquipmentBuilder> equipmentField; Result <List <Item> > inventoryField; while ((token = lexer.NextToken()).Type != Tokens.Eof && token.Type != Tokens.None) { switch (token.Type) { case Tokens.Unknown: return(ReportError(fileName, token, lastToken)); case Tokens.Id: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Id = numberField.Value; break; case Tokens.Name: stringField = ParseStringField(ref lexer); if (!stringField.Success) { return(ReportError(fileName, token, lastToken)); } player.Name = stringField.Value; break; case Tokens.Password: stringField = ParseStringField(ref lexer); if (!stringField.Success) { return(ReportError(fileName, token, lastToken)); } player.Password = stringField.Value; break; case Tokens.Position: posField = ParsePositionField(ref lexer); if (!posField.Success) { return(ReportError(fileName, token, lastToken)); } player.Position = posField.Value; break; case Tokens.TemplePosition: posField = ParsePositionField(ref lexer); if (!posField.Success) { return(ReportError(fileName, token, lastToken)); } player.TemplePosition = posField.Value; break; case Tokens.Outfit: outfitField = ParseOutfitField(ref lexer); if (!outfitField.Success) { return(ReportError(fileName, token, lastToken)); } player.Outfit = outfitField.Value; break; case Tokens.Level: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Level = numberField.Value; break; case Tokens.Experience: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Experience = numberField.Value; break; case Tokens.Health: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Hitpoints = numberField.Value; break; case Tokens.MaxHealth: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.MaxHitpoints = numberField.Value; break; case Tokens.Mana: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Mana = numberField.Value; break; case Tokens.MaxMana: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.MaxMana = numberField.Value; break; case Tokens.Capacity: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Capacity = numberField.Value; break; case Tokens.MagicLevel: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.MagicLevel = numberField.Value; break; case Tokens.MagicLevelExp: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.MagicLevelExp = numberField.Value; break; case Tokens.Fist: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Fist = numberField.Value; break; case Tokens.FistExp: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.FistExp = numberField.Value; break; case Tokens.Club: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Club = numberField.Value; break; case Tokens.ClubExp: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.ClubExp = numberField.Value; break; case Tokens.Sword: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Sword = numberField.Value; break; case Tokens.SwordExp: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.SwordExp = numberField.Value; break; case Tokens.Axe: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Axe = numberField.Value; break; case Tokens.AxeExp: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.AxeExp = numberField.Value; break; case Tokens.Distance: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Dist = numberField.Value; break; case Tokens.DistanceExp: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.DistExp = numberField.Value; break; case Tokens.Shielding: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Shield = numberField.Value; break; case Tokens.ShieldingExp: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.ShieldExp = numberField.Value; break; case Tokens.Fishing: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.Fish = numberField.Value; break; case Tokens.FishingExp: numberField = ParseNumberField(ref lexer); if (!numberField.Success) { return(ReportError(fileName, token, lastToken)); } player.FishExp = numberField.Value; break; case Tokens.Equipment: equipmentField = ParseEquipmentField(ref lexer); if (!equipmentField.Success) { return(ReportError(fileName, token, lastToken)); } player.Equipment = equipmentField.Value; break; case Tokens.Inventory: inventoryField = ParseInventoryField(ref lexer); if (!inventoryField.Success) { return(ReportError(fileName, token, lastToken)); } player.Inventory = inventoryField.Value; break; case Tokens.IsAdmin: boolField = ParseBoolField(ref lexer); if (!boolField.Success) { return(ReportError(fileName, token, lastToken)); } player.IsGm = boolField.Value; break; default: return(ReportError(fileName, token, lastToken)); } lastToken = token; } return(player.Build()); }