steamd 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +4 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +6 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +21 -0
  9. data/README.md +51 -0
  10. data/Rakefile +22 -0
  11. data/bin/console +6 -0
  12. data/bin/setup +6 -0
  13. data/bin/steamd +6 -0
  14. data/grammar/class.treetop +63 -0
  15. data/grammar/enums.treetop +44 -0
  16. data/grammar/import.treetop +11 -0
  17. data/grammar/shared.treetop +62 -0
  18. data/grammar/steamd.treetop +15 -0
  19. data/language/emsg.steamd +1802 -0
  20. data/language/enums.steamd +989 -0
  21. data/language/eresult.steamd +119 -0
  22. data/language/gamecoordinator.steamd +17 -0
  23. data/language/header.steamd +37 -0
  24. data/language/netheader.steamd +62 -0
  25. data/language/steammsg.steamd +357 -0
  26. data/lib/ext/string.rb +33 -0
  27. data/lib/steamd.rb +40 -0
  28. data/lib/steamd/cli.rb +24 -0
  29. data/lib/steamd/cli_options.rb +58 -0
  30. data/lib/steamd/code_generator.rb +41 -0
  31. data/lib/steamd/generated/emsg.rb +3464 -0
  32. data/lib/steamd/generated/enums.rb +1750 -0
  33. data/lib/steamd/generated/eresult.rb +236 -0
  34. data/lib/steamd/generated/gamecoordinator.rb +119 -0
  35. data/lib/steamd/generated/header.rb +261 -0
  36. data/lib/steamd/generated/netheader.rb +315 -0
  37. data/lib/steamd/generated/steammsg.rb +2527 -0
  38. data/lib/steamd/generator.rb +6 -0
  39. data/lib/steamd/generator/generated_class.rb +128 -0
  40. data/lib/steamd/generator/generated_enum.rb +60 -0
  41. data/lib/steamd/generator/generated_import.rb +21 -0
  42. data/lib/steamd/generator/implementation.rb +83 -0
  43. data/lib/steamd/generator/ruby/class.erb +39 -0
  44. data/lib/steamd/generator/ruby/enum.erb +14 -0
  45. data/lib/steamd/generator/ruby/import.erb +1 -0
  46. data/lib/steamd/generator/ruby/ruby.rb +54 -0
  47. data/lib/steamd/generator/ruby/serializable_constant.rb +20 -0
  48. data/lib/steamd/generator/ruby/serializable_type.rb +93 -0
  49. data/lib/steamd/generator/ruby/serializable_variable.rb +85 -0
  50. data/lib/steamd/generator/ruby/steam_serializable.rb +89 -0
  51. data/lib/steamd/nodes/block_node.rb +14 -0
  52. data/lib/steamd/nodes/class_statement_node.rb +46 -0
  53. data/lib/steamd/nodes/class_type_node.rb +12 -0
  54. data/lib/steamd/nodes/enum_statement_node.rb +50 -0
  55. data/lib/steamd/nodes/enum_variable_node.rb +24 -0
  56. data/lib/steamd/nodes/import_statement_node.rb +26 -0
  57. data/lib/steamd/nodes/node.rb +3 -0
  58. data/lib/steamd/nodes/nodes.rb +10 -0
  59. data/lib/steamd/nodes/variable_node.rb +106 -0
  60. data/lib/steamd/parser.rb +157 -0
  61. data/lib/steamd/version.rb +14 -0
  62. data/steamd.gemspec +38 -0
  63. data/tasks/language.rake +11 -0
  64. metadata +220 -0
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ module Steamd
3
+ # Handles code generation
4
+ module Generator
5
+ end
6
+ end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+ require 'ostruct'
3
+ module Steamd
4
+ module Generator
5
+ # Represents an class variable from the Generator
6
+ class Variable
7
+ # The name of the Variable
8
+ attr_reader :name
9
+
10
+ # The variable Type
11
+ attr_reader :type
12
+
13
+ # The variable size
14
+ attr_reader :size
15
+
16
+ # The variable modifier
17
+ attr_reader :modifier
18
+
19
+ # The variable modifier size
20
+ attr_reader :modifier_size
21
+
22
+ # The variable value
23
+ attr_reader :value
24
+
25
+ # Create a new GeneratedClass
26
+ def initialize(opts)
27
+ @name = opts[:name]
28
+ @value = opts[:value]
29
+ @type = opts[:type]
30
+ @modifier = opts[:modifier]
31
+ @modifier_size = opts[:modifier_size]
32
+ end
33
+
34
+ # The name of the Variable
35
+ #
36
+ # @return [String] variable name, underscored
37
+ def name
38
+ @name.underscore
39
+ end
40
+
41
+ # The size of the variable modifier
42
+ #
43
+ # @return [String]
44
+ def modifier_size
45
+ if @modifier_size.is_a?(String)
46
+ @modifier_size.underscore
47
+ else
48
+ @modifier_size
49
+ end
50
+ end
51
+
52
+ # The type of the variable
53
+ def type
54
+ case @type
55
+ when 'SteamKit2.Internal.CMsgProtoBufHeader'
56
+ 'Steamclient::CMsgProtoBufHeader'
57
+ when 'SteamKit2.GC.Internal.CMsgProtoBufHeader'
58
+ 'Gc::CMsgProtoBufHeader'
59
+ else
60
+ @type
61
+ end
62
+ end
63
+
64
+ def value
65
+ if @value.is_a?(String)
66
+ parts = @value.split('::')
67
+ name = parts.last.underscore.upcase
68
+ [parts.first, name].join('::')
69
+ else
70
+ @value
71
+ end
72
+ end
73
+
74
+ # Return the variable as a hash
75
+ def to_hash
76
+ {
77
+ name: name,
78
+ type: type,
79
+ modifier: modifier,
80
+ value: value,
81
+ size: size,
82
+ modifier_size: modifier_size
83
+ }
84
+ end
85
+ alias to_h to_hash
86
+ end
87
+
88
+ # Class constant
89
+ class Constant < Variable
90
+ attr_reader :name, :value
91
+ def name
92
+ @name.underscore.upcase
93
+ end
94
+ end
95
+
96
+ # Represents an Class from the Generator
97
+ class GeneratedClass
98
+ # Create a Generated Class
99
+ def initialize(klass)
100
+ @klass = klass
101
+ end
102
+
103
+ # List of variables to be used in the class
104
+ def variables
105
+ @klass[:variables].select { |v| v[:modifier] != 'const' }.map do |var|
106
+ Variable.new(var)
107
+ end
108
+ end
109
+
110
+ # List of constants to be used in the class
111
+ def constants
112
+ @klass[:variables].select { |v| v[:modifier] == 'const' }.map do |const|
113
+ Constant.new(const)
114
+ end
115
+ end
116
+
117
+ # The class name
118
+ def name
119
+ @klass[:name]
120
+ end
121
+
122
+ # Binding for ERB
123
+ def erb_binding
124
+ binding
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+ module Steamd
3
+ module Generator
4
+ # Enum variable
5
+ class EnumVariable
6
+ attr_reader :name, :value, :flags
7
+ def initialize(name, value, flags)
8
+ @name = name
9
+ @value = value
10
+ @flags = flags
11
+ end
12
+
13
+ def name
14
+ @name.underscore.upcase
15
+ end
16
+
17
+ def value
18
+ if flags && @value.is_a?(String)
19
+ @value
20
+ .split('|')
21
+ .map(&:strip)
22
+ .map(&:underscore)
23
+ .map(&:upcase)
24
+ .join(' | ')
25
+ else
26
+ @value
27
+ end
28
+ end
29
+ end
30
+
31
+ # Represents an Enum from the Generator
32
+ class GeneratedEnum
33
+ def initialize(enum)
34
+ @enum = enum
35
+ end
36
+
37
+ # Type of Enum
38
+ def type
39
+ @enum[:type]
40
+ end
41
+
42
+ # Entries of enum
43
+ def variables
44
+ @enum[:variables].map do |v|
45
+ EnumVariable.new(v[:name], v[:value], @enum[:flags])
46
+ end
47
+ end
48
+
49
+ # Name of enum
50
+ def name
51
+ @enum[:name]
52
+ end
53
+
54
+ # Binding for ERB
55
+ def erb_binding
56
+ binding
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ module Steamd
3
+ module Generator
4
+ # Represents an import from the Generator
5
+ class GeneratedImport
6
+ def initialize(import)
7
+ @import = import
8
+ end
9
+
10
+ # Import filename
11
+ def filename
12
+ @import[:filename]
13
+ end
14
+
15
+ # ERB Binding
16
+ def erb_binding
17
+ binding
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+ require 'erb'
3
+ require 'ostruct'
4
+
5
+ require 'steamd/generator/generated_class'
6
+ require 'steamd/generator/generated_enum'
7
+ require 'steamd/generator/generated_import'
8
+
9
+ module Steamd
10
+ module Generator
11
+ # The underlying Implementation of a generator.
12
+ #
13
+ # @example Making a generate
14
+ # class MyGenerator
15
+ # include Generator::Implementation
16
+ #
17
+ # def generate
18
+ # classes.each { |c| puts c.name }
19
+ # end
20
+ # end
21
+ module Implementation
22
+ # Instantiate the object with a given IO stream.
23
+ #
24
+ # @param io The IO object
25
+ def initialize(io)
26
+ @parser = Steamd::Parser.new
27
+ @buffer = ''
28
+ @io = io
29
+ self
30
+ end
31
+
32
+ # Run the generator. Load the parser, and parse the IO object.
33
+ #
34
+ # @return The parsed code
35
+ def run
36
+ @parser.load!
37
+ @parser.parse(@io)
38
+ generate
39
+ @buffer
40
+ end
41
+
42
+ # The classes parsed from the lanaguage
43
+ def classes
44
+ @parser.classes.map do |klass|
45
+ GeneratedClass.new(klass)
46
+ end
47
+ end
48
+
49
+ # The imports parsed from the language
50
+ def imports
51
+ @parser.imports.map do |import|
52
+ GeneratedImport.new(import)
53
+ end
54
+ end
55
+
56
+ # The enums parsed from the language
57
+ def enums
58
+ @parser.enums.map do |enum|
59
+ GeneratedEnum.new(enum)
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ # Generates the code
66
+ def generate(_io)
67
+ raise NotImplementedError
68
+ end
69
+
70
+ # @api private
71
+ def erb(template, vars)
72
+ ERB.new(template, nil, '-').result(vars.erb_binding)
73
+ end
74
+
75
+ # Append a string to the internal buffer
76
+ #
77
+ # @api private
78
+ def append(str)
79
+ @buffer += str
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,39 @@
1
+ # Class for the <%= name %> in the Steam Language.
2
+ class <%= name %>
3
+ # Allows serialization and deserialization of the class
4
+ include SteamSerializable
5
+
6
+ <% constants.each do |const| -%>
7
+ # <%= const.name -%> constant
8
+ <%= const.name -%> = <%= const.value %>
9
+ <% end -%>
10
+ # Instantiate a <%= name -%> object
11
+ def initialize
12
+ super(<%= variables.map(&:to_h) -%>, <%= constants.map(&:to_h) -%>)
13
+ <% variables.each do |var| -%>
14
+ <% if var.value != nil -%>
15
+ self.<%= var.name -%> = <%= var.value %>
16
+ <% end -%>
17
+ <% if var.type.include?('CMsg') -%>
18
+ self.<%= var.name -%> = <%= var.type %>.new
19
+ <% end -%>
20
+ <% end -%>
21
+ end
22
+ <% variables.each do |var| %>
23
+ # Gets the <%= var.name -%> variable.
24
+ #
25
+ # @note defaults to <%= var.value %>
26
+ # @return [<%= var.type -%>] the value of <%= var.name %>
27
+ def <%= var.name %>
28
+ @variables['<%= var.name -%>'][:value]
29
+ end
30
+
31
+ # Sets the <%= var.name -%> variable.
32
+ #
33
+ # @param value [<%= var.type -%>] the new value
34
+ def <%= var.name -%>=(value)
35
+ @variables['<%= var.name -%>'][:value] = value
36
+ end
37
+ <% end %>
38
+ end
39
+
@@ -0,0 +1,14 @@
1
+ # Represents the <%= name -%> enum
2
+ class <%= name %>
3
+ # Data type of <%= name %>
4
+ <% if type -%>
5
+ DATA_TYPE = '<%= type %>'
6
+ <% else -%>
7
+ DATA_TYPE = 'int'
8
+ <% end -%>
9
+ <% variables.each do |var| -%>
10
+ # Constant <%= var.name -%> for <%= name %>
11
+ <%= var.name %> = <%= var.value %>
12
+ <% end -%>
13
+ end
14
+
@@ -0,0 +1 @@
1
+ require_relative '<%= filename %>'
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+ require 'steamd/generator/implementation'
3
+
4
+ # frozen_string_literal: true
5
+ module Steamd
6
+ module Generator
7
+ # Generates Ruby code
8
+ class Ruby
9
+ include Implementation
10
+
11
+ # Generate Ruby code for the Steam Language
12
+ def generate
13
+ classes.each do |klass|
14
+ append(erb(klass_template, klass))
15
+ end
16
+
17
+ imports.each do |import|
18
+ append(erb(import_template, import))
19
+ end
20
+
21
+ enums.each do |enum|
22
+ append(erb(enum_template, enum))
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ # @api private
29
+ def import_template
30
+ erb_file('import.erb').read
31
+ end
32
+
33
+ # @api private
34
+ def enum_template
35
+ erb_file('enum.erb').read
36
+ end
37
+
38
+ # @api private
39
+ def klass_template
40
+ erb_file('class.erb').read
41
+ end
42
+
43
+ # @api private
44
+ def erb_file(file)
45
+ File.open(File.expand_path("#{erb_template_root}/#{file}"))
46
+ end
47
+
48
+ # @api private
49
+ def erb_template_root
50
+ File.dirname(__FILE__)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ # Serializable const
3
+ class SerizableConstant < SerizableVariable
4
+ # Override the type for constants, always integer
5
+ #
6
+ # @return [Type]
7
+ def type
8
+ Type.new('int')
9
+ end
10
+
11
+ # Serialize the constant
12
+ def serialize
13
+ serialize_primitive
14
+ end
15
+
16
+ # Deserialize the constant
17
+ def deserialize
18
+ @value = deserialize_primitive
19
+ end
20
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+ # Serializable type
3
+ class Type
4
+ attr_reader :type
5
+
6
+ # Instantiate a Type
7
+ #
8
+ # @example Instantiate a Type
9
+ # type = Type.new('int')
10
+ def initialize(type)
11
+ @type = type
12
+ end
13
+
14
+ # The String representation of the Type. If it is a SteamKit Internal type,
15
+ # the type is transformed into namespaces from the `steam-proto` repo.
16
+ #
17
+ # @return [String] the type
18
+ def type
19
+ case @type
20
+ when 'SteamKit2.Internal.CMsgProtoBufHeader'
21
+ 'Steamclient::CMsgProtoBufHeader'
22
+ when 'SteamKit2.GC.Internal.CMsgProtoBufHeader'
23
+ 'Gc::CMsgProtoBufHeader'
24
+ when *primitives
25
+ @type
26
+ else
27
+ Object.const_get(@type.to_s).to_s
28
+ end
29
+ end
30
+
31
+ # Is this type an encodable type?
32
+ #
33
+ # @return [Bool]
34
+ def encodable?
35
+ encodables.include?(type)
36
+ end
37
+
38
+ # Is this type an primitive type?
39
+ #
40
+ # @return [Bool]
41
+ def primitive?
42
+ primitives.include?(type)
43
+ end
44
+
45
+ # The byte directive for this type
46
+ #
47
+ # @return [String]
48
+ def bytedirective
49
+ {
50
+ 'int' => 'l<',
51
+ 'ushort' => 'S<',
52
+ 'short' => 's<',
53
+ 'byte' => 'c',
54
+ 'uint' => 'L<',
55
+ 'ulong' => 'Q<'
56
+ }[type]
57
+ end
58
+
59
+ # The size in bytes of this type
60
+ #
61
+ # @return [Integer]
62
+ def bytesize
63
+ case type
64
+ when 'uint', 'int'
65
+ 4
66
+ when 'ushort', 'short'
67
+ 2
68
+ when 'ulong', 'long'
69
+ 8
70
+ when 'byte'
71
+ 1
72
+ end
73
+ end
74
+
75
+ # The Class represented by this Type
76
+ #
77
+ # @return [Object]
78
+ def klass
79
+ type.constantize
80
+ end
81
+
82
+ private
83
+
84
+ # @api private
85
+ def primitives
86
+ %w(int short uint long ulong byte ushort)
87
+ end
88
+
89
+ # @api private
90
+ def encodables
91
+ ['Steamclient::CMsgProtoBufHeader', 'Gc::CMsgProtoBufHeader']
92
+ end
93
+ end