GithubHelp home page GithubHelp logo

galaco / keyvalues Goto Github PK

View Code? Open in Web Editor NEW
6.0 3.0 2.0 29 KB

Source engine KeyValue format parser (e.g. gameinfo.txt, vmt, vmf)

License: The Unlicense

Go 100.00%
source-engine valve gameinfo vmt keyvalue-files keyvalue game-info

keyvalues's Introduction

GoDoc Go report card Build Status

keyvalues

A zero-dependency library for Parsing Valve KeyValue format data.

Go library for parsing Valve keyvalue format files. This library constructs a simple kv node tree that you can query any structure(s) and any property(s) of.

It has been tested against various gameinfo.txt engine files, but should work with other KeyValue files as well (such as .vmf or .vmt).

It is important to note that KeyValue's appear to support (in certain rare uses of the format) multiple root nodes in a single definition. This package will create a root node with Key $root in this situation, with all root nodes as children. If there is only a single root node, the root node will be as defined in the KeyValues.

Usage

package main

import (
    "log"
    "os"
    "github.com/galaco/keyvalues"
)

func main() {
	file,_ := os.Open("gameinfo.txt")

	reader := keyvalues.NewReader(file)
	kv,_ := reader.Read()

    // counterstrike: source's gameinfo.txt would return "Counter-Strike Source"
    gameInfoNode,_ := kv.Find("GameInfo")
    gameNode,_ := gameInfoNode.Find("game")
    log.Println(gameNode.AsString())

    // counterstrike: source's gameinfo.txt would return 1
    noModelsNode,_ := gameInfoNode.Find("nomodels")
    log.Println(noModelsNode.AsInt())

    // counterstrike: source's gameinfo.txt would return 240
    fileSystemNode,_ := gameInfoNode.Find("FileSystem")
    appIdNode,_ := fileSystemNode.Find("SteamAppId")
    log.Println(appIdNode.AsInt())
}

Todo

  • Implement multi-line values. At present, a \n character in a quoted value will break the parser. This is how CS:GO Hammer behaves. However, other versions of Hammer support this, as well as all engine versions. Worth noting what spec is available doesn't cover this behaviour.
  • Implement pointer value type (unsure if there is any point to this besides matching spec)
  • Proper test coverage

keyvalues's People

Contributors

galaco avatar hugmouse avatar ss23 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

keyvalues's Issues

Case-insensitive key search

Format documentation doesn't specify rules around keys, however there doesn't appear to be any known case of the same key appearing in different cases in the same file, that represents data with a different use case.

To better support usage of the format, case-insensitive key searching makes sense to ease variations to keys

Refactor `keyvalue.MergeInto()` to handle 'include' and 'patch' rules correctly

MergeInto needs some refactoring to correctly handle the include and patch rules.

Right now MergeInto is basically a patch implementation, that ignores what the root key is (should be either include or patch i feel).

MergeInto can either be split into 2 functions, or provide a generic method that calls some internal methods for each case. The caller would know what is performed, as they have access to the root key that defines the merge type.

include will add any missing KeyValues into a tree, patch will both add and replace existing keys.

Multi-line value support

Some valve implementations (there are several... ๐Ÿ‘Ž ) support multi-line values (exclusively using the '\n' character).
Hammer variations are a good example that support vmfs with this feature in pre-CSGO versions, yet post-CSGO versions will crash.

This library currently doesn't newlines, but it should do

Duplicate keys

The spec allows for the same key to be declared multiple times in a scope. The library currently reads this correctly, but does not provide a mechanism to get the parsed kvs, except the first occurrence.

Add method to KeyValue as FindAllByKey() that returns all kvs with that keyname

Wildcard key search

Add support for wildcard key searches. regexp is probably the best way forward here, perhaps masked away with a simplified syntax such as <key>* or *<key>.

I would argue that wildcard searches should be simple; more advanced regex searches should be written by user. The limit to this feature should be wildcard *, the same as targetname wildcards in source engine entities, which follows the same keyvalue rules.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.