1
- /*
2
- Adapted from go-steam's generator/generator.go to generate dota 2 proto files.
3
-
4
- https://github.com/Philipp15b/go-steam/blob/master/generator/generator.go
5
-
6
- -------------------------------------------------------------------------------
7
-
8
- Copyright (c) 2014 The go-steam Authors. All rights reserved.
9
-
10
- Redistribution and use in source and binary forms, with or without
11
- modification, are permitted provided that the following conditions are
12
- met:
13
-
14
- * Redistributions of source code must retain the above copyright
15
- notice, this list of conditions and the following disclaimer.
16
- * Redistributions in binary form must reproduce the above
17
- copyright notice, this list of conditions and the following disclaimer
18
- in the documentation and/or other materials provided with the
19
- distribution.
20
- * The names of its contributors may not be used to endorse or promote
21
- products derived from this software without specific prior written permission.
22
-
23
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
-
35
- */
36
-
37
- /*
38
- This program generates the protobuf and SteamLanguage files from the SteamKit data.
39
- */
40
1
package main
41
2
42
3
import (
43
4
"bytes"
44
- "go/parser"
45
- "go/token"
5
+ gofmt "go/format"
46
6
"io"
47
7
"io/ioutil"
48
8
"os"
@@ -53,6 +13,7 @@ import (
53
13
)
54
14
55
15
var printCommands = false
16
+ var pkgImportPath = "github.com/paralin/go-dota2/protocol"
56
17
57
18
func main () {
58
19
args := strings .Join (os .Args [1 :], " " )
@@ -106,11 +67,14 @@ func buildProtoMap(files map[string]string, outDir string) {
106
67
// Maps the proto files to their target files.
107
68
// See `SteamKit/Resources/Protobufs/steamclient/generate-base.bat` for reference.
108
69
var dota2ProtoFiles = map [string ]string {
109
- "base_gcmessages.proto" : "base.pb.go" ,
110
- "gcsdk_gcmessages.proto" : "gcsdk.pb.go" ,
111
- "dota_gcmessages_client.proto" : "dota_client.pb.go" ,
112
- "dota_gcmessages_common.proto" : "dota_common.pb.go" ,
113
- "gcsystemmsgs.proto" : "system.pb.go" ,
70
+ "base_gcmessages.proto" : "base.pb.go" ,
71
+ "gcsdk_gcmessages.proto" : "gcsdk.pb.go" ,
72
+ "dota_gcmessages_client.proto" : "dota_client.pb.go" ,
73
+ "dota_gcmessages_common.proto" : "dota_common.pb.go" ,
74
+ "dota_gcmessages_common_match_management.proto" : "dota_common_match_management.pb.go" ,
75
+ "dota_shared_enums.proto" : "dota_shared_enums.pb.go" ,
76
+ "steammessages.proto" : "steammessages.pb.go" ,
77
+ "gcsystemmsgs.proto" : "system.pb.go" ,
114
78
}
115
79
116
80
func compileProto (srcBase , proto , target string ) {
@@ -134,52 +98,65 @@ func forceRename(from, to string) error {
134
98
return os .Rename (from , to )
135
99
}
136
100
137
- var pkgRegex = regexp .MustCompile (`(package \w+)` )
101
+ var pkgRegex = regexp .MustCompile (`(package )( \w+)` )
138
102
var pkgCommentRegex = regexp .MustCompile (`(?s)(\/\*.*?\*\/\n)package` )
103
+ var localImportRegex = regexp .MustCompile (`(import )(\w+)( ".")` )
139
104
140
105
func fixProto (path string ) {
141
106
// goprotobuf is really bad at dependencies, so we must fix them manually...
142
107
// It tries to load each dependency of a file as a seperate package (but in a very, very wrong way).
143
108
// Because we want some files in the same package, we'll remove those imports to local files.
144
-
145
109
file , err := ioutil .ReadFile (path )
146
110
if err != nil {
147
111
panic (err )
148
112
}
149
-
150
- fset := token .NewFileSet ()
151
- f , err := parser .ParseFile (fset , path , file , parser .ImportsOnly )
152
- if err != nil {
153
- panic ("Error parsing " + path + ": " + err .Error ())
154
- }
155
-
156
- importsToRemove := make ([]string , 0 )
157
- for _ , i := range f .Imports {
158
- // We remove all imports that include ".pb". This assumes unified and protobuf packages don't share anything.
159
- if i .Name .Name != "google_protobuf" && strings .Contains (i .Path .Value , ".pb" ) {
160
- importsToRemove = append (importsToRemove , i .Name .Name )
161
- }
162
- }
163
-
164
- for _ , itr := range importsToRemove {
165
- // remove the package name from all types
166
- file = bytes .Replace (file , []byte (itr + "." ), []byte {}, - 1 )
167
- // and remove the import itself
168
- file = bytes .Replace (file , []byte ("import " + itr + " \" pb\" \n " ), []byte {}, - 1 )
169
- }
113
+ fileDir := filepath .Dir (path )
170
114
171
115
// remove the package comment because it just includes a list of all messages and
172
116
// creates collisions between the others.
173
117
file = cutAllSubmatch (pkgCommentRegex , file , 1 )
174
118
175
119
// fix the package name
176
- file = pkgRegex .ReplaceAll (file , []byte ("package " + inferPackageName (path )))
120
+ // find the package name
121
+ pkgNameParts := pkgRegex .FindSubmatch (file )
122
+ if len (pkgNameParts ) == 0 {
123
+ panic ("Error determining package name in " + path )
124
+ }
125
+ packageName := string (pkgNameParts [2 ])
177
126
178
127
// fix the google dependency;
179
128
// we just reuse the one from protoc-gen-go
180
129
file = bytes .Replace (file , []byte ("google/protobuf/descriptor.pb" ), []byte ("code.google.com/p/goprotobuf/protoc-gen-go/descriptor" ), - 1 )
130
+ file = bytes .Replace (file , []byte ("import _ \" .\" \n " ), []byte {}, 1 )
131
+ file = bytes .Replace (file , []byte ("import google_protobuf \" google/protobuf\" " ), []byte ("import google_protobuf \" github.com/golang/protobuf/protoc-gen-go/descriptor\" " ), 1 )
132
+
133
+ matches := localImportRegex .FindAllSubmatch (file , - 1 )
134
+ for _ , match := range matches {
135
+ completeMatch := match [0 ]
136
+ pkgName := string (match [2 ])
137
+ replaceWith := "import " + pkgName + " \" " + pkgImportPath + "/" + pkgName + "\" "
138
+ if pkgName == "_" {
139
+ replaceWith = ""
140
+ }
141
+ print ("Replacing " + string (completeMatch ) + " with " + replaceWith )
142
+ file = bytes .Replace (file , completeMatch , []byte (replaceWith ), 1 )
143
+ }
144
+
145
+ pkgSubdir := filepath .Join (fileDir , packageName )
146
+ finalPath := filepath .Join (pkgSubdir , packageName + ".go" )
147
+ if err := os .MkdirAll (pkgSubdir , 0755 ); err != nil {
148
+ panic (err )
149
+ }
150
+
151
+ fmted , err := gofmt .Source (file )
152
+ if err != nil {
153
+ panic (err )
154
+ }
155
+ if err := os .Remove (path ); err != nil {
156
+ panic (err )
157
+ }
181
158
182
- err = ioutil .WriteFile (path , file , os . ModePerm )
159
+ err = ioutil .WriteFile (finalPath , fmted , 0755 )
183
160
if err != nil {
184
161
panic (err )
185
162
}
0 commit comments