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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/.rubocop.yml +4 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +51 -0
- data/Rakefile +22 -0
- data/bin/console +6 -0
- data/bin/setup +6 -0
- data/bin/steamd +6 -0
- data/grammar/class.treetop +63 -0
- data/grammar/enums.treetop +44 -0
- data/grammar/import.treetop +11 -0
- data/grammar/shared.treetop +62 -0
- data/grammar/steamd.treetop +15 -0
- data/language/emsg.steamd +1802 -0
- data/language/enums.steamd +989 -0
- data/language/eresult.steamd +119 -0
- data/language/gamecoordinator.steamd +17 -0
- data/language/header.steamd +37 -0
- data/language/netheader.steamd +62 -0
- data/language/steammsg.steamd +357 -0
- data/lib/ext/string.rb +33 -0
- data/lib/steamd.rb +40 -0
- data/lib/steamd/cli.rb +24 -0
- data/lib/steamd/cli_options.rb +58 -0
- data/lib/steamd/code_generator.rb +41 -0
- data/lib/steamd/generated/emsg.rb +3464 -0
- data/lib/steamd/generated/enums.rb +1750 -0
- data/lib/steamd/generated/eresult.rb +236 -0
- data/lib/steamd/generated/gamecoordinator.rb +119 -0
- data/lib/steamd/generated/header.rb +261 -0
- data/lib/steamd/generated/netheader.rb +315 -0
- data/lib/steamd/generated/steammsg.rb +2527 -0
- data/lib/steamd/generator.rb +6 -0
- data/lib/steamd/generator/generated_class.rb +128 -0
- data/lib/steamd/generator/generated_enum.rb +60 -0
- data/lib/steamd/generator/generated_import.rb +21 -0
- data/lib/steamd/generator/implementation.rb +83 -0
- data/lib/steamd/generator/ruby/class.erb +39 -0
- data/lib/steamd/generator/ruby/enum.erb +14 -0
- data/lib/steamd/generator/ruby/import.erb +1 -0
- data/lib/steamd/generator/ruby/ruby.rb +54 -0
- data/lib/steamd/generator/ruby/serializable_constant.rb +20 -0
- data/lib/steamd/generator/ruby/serializable_type.rb +93 -0
- data/lib/steamd/generator/ruby/serializable_variable.rb +85 -0
- data/lib/steamd/generator/ruby/steam_serializable.rb +89 -0
- data/lib/steamd/nodes/block_node.rb +14 -0
- data/lib/steamd/nodes/class_statement_node.rb +46 -0
- data/lib/steamd/nodes/class_type_node.rb +12 -0
- data/lib/steamd/nodes/enum_statement_node.rb +50 -0
- data/lib/steamd/nodes/enum_variable_node.rb +24 -0
- data/lib/steamd/nodes/import_statement_node.rb +26 -0
- data/lib/steamd/nodes/node.rb +3 -0
- data/lib/steamd/nodes/nodes.rb +10 -0
- data/lib/steamd/nodes/variable_node.rb +106 -0
- data/lib/steamd/parser.rb +157 -0
- data/lib/steamd/version.rb +14 -0
- data/steamd.gemspec +38 -0
- data/tasks/language.rake +11 -0
- metadata +220 -0
@@ -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
|