added code generator

master
Jordan Orelli 9 years ago
parent b89b0df06a
commit 927ce6e9e3

@ -0,0 +1,313 @@
package main
import (
"bytes"
"flag"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"io"
"io/ioutil"
"os"
"strconv"
"strings"
"text/template"
)
var (
messageTypes = make(map[string]bool)
enumTypes = make(map[string]bool)
entityTypes = make(map[int]string)
cmdTypes = make(map[int]string)
cmdEnumType = "EDemoCommands"
entityEnumTypes = map[string]bool{
"NET_Messages": true,
"SVC_Messages": true,
"EBaseUserMessages": true,
"EBaseEntityMessages": true,
"EBaseGameEvents": true,
"EDotaUserMessages": true,
}
prefixes = map[string]string{
"EDemoCommands_DEM_": "CDemo",
"NET_Messages_net_": "CNETMsg_",
"SVC_Messages_svc_": "CSVCMsg_",
"EBaseUserMessages_UM_": "CUserMessage",
"EBaseEntityMessages_EM_": "CEntityMessage",
"EBaseGameEvents_GE_": "CMsg",
"EDotaUserMessages_DOTA_UM_": "CDOTAUserMsg_",
}
specials = map[string]string{
"EDemoCommands_DEM_SignonPacket": "CDemoPacket",
"EDotaUserMessages_DOTA_UM_StatsHeroDetails": "CDOTAUserMsg_StatsHeroMinuteDetails",
"EDotaUserMessages_DOTA_UM_CombatLogDataHLTV": "CMsgDOTACombatLogEntry",
"EDotaUserMessages_DOTA_UM_TournamentDrop": "CMsgGCToClientTournamentItemDrop",
"EDotaUserMessages_DOTA_UM_MatchMetadata": "CDOTAClientMsg_MatchMetadata",
}
skipped = map[string]bool{
"EDemoCommands_DEM_IsCompressed": true,
"EDemoCommands_DEM_Max": true,
"EDotaUserMessages_DOTA_UM_MatchDetails": true,
"EBaseUserMessages_UM_ParticleManager": true,
"EBaseUserMessages_UM_CustomGameEvent": true,
"EDotaUserMessages_DOTA_UM_AddUnitToSelection": true,
"EBaseUserMessages_UM_HudError": true,
"EDotaUserMessages_DOTA_UM_CombatLogData": true,
"EDotaUserMessages_DOTA_UM_CharacterSpeakConcept": true,
}
// EBaseUserMessages_UM_HandHapticPulse
tpl = `package main
/*------------------------------------------------------------------------------
.aMMMb .aMMMb dMMMMb dMMMMMP
dMP"VMP dMP"dMP dMP VMP dMP
dMP dMP dMP dMP dMP dMMMP
dMP.aMP dMP.aMP dMP.aMP dMP
VMMMP" VMMMP" dMMMMP" dMMMMMP
.aMMMMP dMMMMMP dMMMMb dMMMMMP dMMMMb .aMMMb dMMMMMMP dMMMMMP dMMMMb
dMP" dMP dMP dMP dMP dMP.dMP dMP"dMP dMP dMP dMP VMP
dMP MMP"dMMMP dMP dMP dMMMP dMMMMK" dMMMMMP dMP dMMMP dMP dMP
dMP.dMP dMP dMP dMP dMP dMP"AMF dMP dMP dMP dMP dMP.aMP
VMMMP" dMMMMMP dMP dMP dMMMMMP dMP dMP dMP dMP dMP dMMMMMP dMMMMP"
This code was generated by a code-generation program. It was NOT written by
hand. Do not edit this file by hand! Your edits will be destroyed!
This file can be regenerated by running "go generate"
The generator program is defined in "gen/main.go"
------------------------------------------------------------------------------*/
import (
"github.com/golang/protobuf/proto"
"github.com/jordanorelli/hyperstone/dota"
)
type protoFactory map[int]func() proto.Message
func (p protoFactory) BuildMessage(id int) proto.Message {
fn, ok := p[id]
if !ok {
return nil
}
return fn()
}
var cmdFactory = protoFactory{
{{- range $id, $name := .Commands }}
{{$id}}: func() proto.Message { return new(dota.{{$name}}) },
{{- end }}
}
var entFactory = protoFactory{
{{- range $id, $name := .Entities }}
{{$id}}: func() proto.Message { return new(dota.{{$name}}) },
{{- end }}
}
`
)
func ensureNewline(t string) string {
if strings.HasSuffix(t, "\n") {
return t
}
return t + "\n"
}
func bail(status int, t string, args ...interface{}) {
var out io.Writer
if status == 0 {
out = os.Stdout
} else {
out = os.Stderr
}
fmt.Fprintf(out, ensureNewline(t), args...)
os.Exit(status)
}
// processes a single value specification
func processValueSpec(spec *ast.ValueSpec) {
if spec.Type == nil {
return
}
t, ok := spec.Type.(*ast.Ident)
if !ok {
return
}
var isEntityType bool
switch {
case t.Name == cmdEnumType:
// it's a message type
case entityEnumTypes[t.Name]:
isEntityType = true
default:
return
}
for i, name := range spec.Names {
if name.Name == "_" {
continue
}
valExpr := spec.Values[i]
litExpr, ok := valExpr.(*ast.BasicLit)
if !ok {
continue
}
if litExpr.Kind != token.INT {
continue
}
n, err := strconv.Atoi(litExpr.Value)
if err != nil {
continue
}
if isEntityType {
entityTypes[n] = name.Name
} else {
cmdTypes[n] = name.Name
}
}
}
// processes a single type specification from the Go source
// e.g.:
// type Thing int32
// type Message struct {
// ...
// }
func processTypeSpec(spec *ast.TypeSpec) {
switch tt := spec.Type.(type) {
case *ast.StructType:
// the only structes that are defined in our generated proto code are
// protobuf message types
messageTypes[spec.Name.Name] = true
case *ast.Ident:
switch tt.Name {
case "int32":
// all protobuf enums generate int32s in Go
enumTypes[spec.Name.Name] = true
}
}
}
// processes one specification from the Go source
func processSpec(spec ast.Spec) {
switch t := spec.(type) {
case *ast.ValueSpec:
processValueSpec(t)
case *ast.TypeSpec:
processTypeSpec(t)
}
}
// processes one protobuf-generated Go declaration
func processDeclaration(decl ast.Decl) {
d, ok := decl.(*ast.GenDecl)
if !ok {
return
}
for _, spec := range d.Specs {
processSpec(spec)
}
}
// processes one protobuf-generated Go file
func processFile(name string, fi *ast.File) {
for _, decl := range fi.Decls {
processDeclaration(decl)
}
}
// processes a package of protobuf-generated Go
func processPackage(name string, pkg *ast.Package) {
for name, fi := range pkg.Files {
processFile(name, fi)
}
}
// given an enum name, finds the appropriate message type
func typeName(enumName string) string {
for prefix, replacement := range prefixes {
if strings.HasPrefix(enumName, prefix) {
candidate := strings.Replace(enumName, prefix, replacement, 1)
if messageTypes[candidate] {
return candidate
}
}
}
return ""
}
func main() {
flag.Parse()
if flag.NArg() != 1 {
bail(1, "gen should get exactly one argument: the directory to operate on")
}
path := flag.Arg(0)
fs := token.NewFileSet()
packages, err := parser.ParseDir(fs, path, nil, 0)
if err != nil {
bail(1, "go parser error: %v", err)
}
for name, pkg := range packages {
processPackage(name, pkg)
}
type typeMap map[int]string
type context struct {
Commands typeMap
Entities typeMap
}
ctx := context{make(typeMap), make(typeMap)}
for id, name := range cmdTypes {
realName := typeName(name)
if realName == "" {
continue
}
ctx.Commands[id] = realName
}
for id, name := range entityTypes {
realName := typeName(name)
if realName == "" {
continue
}
ctx.Entities[id] = realName
}
t, err := template.New("out.go").Parse(tpl)
if err != nil {
bail(1, "bad template: %v", err)
}
buf := bytes.NewBuffer(nil)
if err := t.Execute(buf, ctx); err != nil {
bail(1, "template error: %v", err)
}
source, err := format.Source(buf.Bytes())
if err != nil {
bail(1, "fmt error: %v", err)
}
if err := ioutil.WriteFile("generated.go", source, 0644); err != nil {
bail(1, "error writing source output: %v", err)
}
}

@ -0,0 +1,239 @@
package main
/*------------------------------------------------------------------------------
.aMMMb .aMMMb dMMMMb dMMMMMP
dMP"VMP dMP"dMP dMP VMP dMP
dMP dMP dMP dMP dMP dMMMP
dMP.aMP dMP.aMP dMP.aMP dMP
VMMMP" VMMMP" dMMMMP" dMMMMMP
.aMMMMP dMMMMMP dMMMMb dMMMMMP dMMMMb .aMMMb dMMMMMMP dMMMMMP dMMMMb
dMP" dMP dMP dMP dMP dMP.dMP dMP"dMP dMP dMP dMP VMP
dMP MMP"dMMMP dMP dMP dMMMP dMMMMK" dMMMMMP dMP dMMMP dMP dMP
dMP.dMP dMP dMP dMP dMP dMP"AMF dMP dMP dMP dMP dMP.aMP
VMMMP" dMMMMMP dMP dMP dMMMMMP dMP dMP dMP dMP dMP dMMMMMP dMMMMP"
This code was generated by a code-generation program. It was NOT written by
hand. Do not edit this file by hand! Your edits will be destroyed!
This file can be regenerated by running "go generate"
The generator program is defined in "gen/main.go"
------------------------------------------------------------------------------*/
import (
"github.com/golang/protobuf/proto"
"github.com/jordanorelli/hyperstone/dota"
)
type protoFactory map[int]func() proto.Message
func (p protoFactory) BuildMessage(id int) proto.Message {
fn, ok := p[id]
if !ok {
return nil
}
return fn()
}
var cmdFactory = protoFactory{
0: func() proto.Message { return new(dota.CDemoStop) },
1: func() proto.Message { return new(dota.CDemoFileHeader) },
2: func() proto.Message { return new(dota.CDemoFileInfo) },
3: func() proto.Message { return new(dota.CDemoSyncTick) },
4: func() proto.Message { return new(dota.CDemoSendTables) },
5: func() proto.Message { return new(dota.CDemoClassInfo) },
6: func() proto.Message { return new(dota.CDemoStringTables) },
7: func() proto.Message { return new(dota.CDemoPacket) },
9: func() proto.Message { return new(dota.CDemoConsoleCmd) },
10: func() proto.Message { return new(dota.CDemoCustomData) },
11: func() proto.Message { return new(dota.CDemoCustomDataCallbacks) },
12: func() proto.Message { return new(dota.CDemoUserCmd) },
13: func() proto.Message { return new(dota.CDemoFullPacket) },
14: func() proto.Message { return new(dota.CDemoSaveGame) },
15: func() proto.Message { return new(dota.CDemoSpawnGroups) },
}
var entFactory = protoFactory{
0: func() proto.Message { return new(dota.CNETMsg_NOP) },
1: func() proto.Message { return new(dota.CNETMsg_Disconnect) },
3: func() proto.Message { return new(dota.CNETMsg_SplitScreenUser) },
4: func() proto.Message { return new(dota.CNETMsg_Tick) },
5: func() proto.Message { return new(dota.CNETMsg_StringCmd) },
6: func() proto.Message { return new(dota.CNETMsg_SetConVar) },
7: func() proto.Message { return new(dota.CNETMsg_SignonState) },
8: func() proto.Message { return new(dota.CNETMsg_SpawnGroup_Load) },
9: func() proto.Message { return new(dota.CNETMsg_SpawnGroup_ManifestUpdate) },
11: func() proto.Message { return new(dota.CNETMsg_SpawnGroup_SetCreationTick) },
12: func() proto.Message { return new(dota.CNETMsg_SpawnGroup_Unload) },
13: func() proto.Message { return new(dota.CNETMsg_SpawnGroup_LoadCompleted) },
40: func() proto.Message { return new(dota.CSVCMsg_ServerInfo) },
41: func() proto.Message { return new(dota.CSVCMsg_FlattenedSerializer) },
42: func() proto.Message { return new(dota.CSVCMsg_ClassInfo) },
43: func() proto.Message { return new(dota.CSVCMsg_SetPause) },
44: func() proto.Message { return new(dota.CSVCMsg_CreateStringTable) },
45: func() proto.Message { return new(dota.CSVCMsg_UpdateStringTable) },
46: func() proto.Message { return new(dota.CSVCMsg_VoiceInit) },
47: func() proto.Message { return new(dota.CSVCMsg_VoiceData) },
48: func() proto.Message { return new(dota.CSVCMsg_Print) },
49: func() proto.Message { return new(dota.CSVCMsg_Sounds) },
50: func() proto.Message { return new(dota.CSVCMsg_SetView) },
51: func() proto.Message { return new(dota.CSVCMsg_ClearAllStringTables) },
52: func() proto.Message { return new(dota.CSVCMsg_CmdKeyValues) },
53: func() proto.Message { return new(dota.CSVCMsg_BSPDecal) },
54: func() proto.Message { return new(dota.CSVCMsg_SplitScreen) },
55: func() proto.Message { return new(dota.CSVCMsg_PacketEntities) },
56: func() proto.Message { return new(dota.CSVCMsg_Prefetch) },
57: func() proto.Message { return new(dota.CSVCMsg_Menu) },
58: func() proto.Message { return new(dota.CSVCMsg_GetCvarValue) },
59: func() proto.Message { return new(dota.CSVCMsg_StopSound) },
60: func() proto.Message { return new(dota.CSVCMsg_PeerList) },
61: func() proto.Message { return new(dota.CSVCMsg_PacketReliable) },
62: func() proto.Message { return new(dota.CSVCMsg_HLTVStatus) },
63: func() proto.Message { return new(dota.CSVCMsg_ServerSteamID) },
70: func() proto.Message { return new(dota.CSVCMsg_FullFrameSplit) },
101: func() proto.Message { return new(dota.CUserMessageAchievementEvent) },
102: func() proto.Message { return new(dota.CUserMessageCloseCaption) },
103: func() proto.Message { return new(dota.CUserMessageCloseCaptionDirect) },
104: func() proto.Message { return new(dota.CUserMessageCurrentTimescale) },
105: func() proto.Message { return new(dota.CUserMessageDesiredTimescale) },
106: func() proto.Message { return new(dota.CUserMessageFade) },
107: func() proto.Message { return new(dota.CUserMessageGameTitle) },
109: func() proto.Message { return new(dota.CUserMessageHintText) },
110: func() proto.Message { return new(dota.CUserMessageHudMsg) },
111: func() proto.Message { return new(dota.CUserMessageHudText) },
112: func() proto.Message { return new(dota.CUserMessageKeyHintText) },
113: func() proto.Message { return new(dota.CUserMessageColoredText) },
114: func() proto.Message { return new(dota.CUserMessageRequestState) },
115: func() proto.Message { return new(dota.CUserMessageResetHUD) },
116: func() proto.Message { return new(dota.CUserMessageRumble) },
117: func() proto.Message { return new(dota.CUserMessageSayText) },
118: func() proto.Message { return new(dota.CUserMessageSayText2) },
119: func() proto.Message { return new(dota.CUserMessageSayTextChannel) },
120: func() proto.Message { return new(dota.CUserMessageShake) },
121: func() proto.Message { return new(dota.CUserMessageShakeDir) },
124: func() proto.Message { return new(dota.CUserMessageTextMsg) },
125: func() proto.Message { return new(dota.CUserMessageScreenTilt) },
126: func() proto.Message { return new(dota.CUserMessageTrain) },
127: func() proto.Message { return new(dota.CUserMessageVGUIMenu) },
128: func() proto.Message { return new(dota.CUserMessageVoiceMask) },
129: func() proto.Message { return new(dota.CUserMessageVoiceSubtitle) },
130: func() proto.Message { return new(dota.CUserMessageSendAudio) },
131: func() proto.Message { return new(dota.CUserMessageItemPickup) },
132: func() proto.Message { return new(dota.CUserMessageAmmoDenied) },
133: func() proto.Message { return new(dota.CUserMessageCrosshairAngle) },
134: func() proto.Message { return new(dota.CUserMessageShowMenu) },
135: func() proto.Message { return new(dota.CUserMessageCreditsMsg) },
136: func() proto.Message { return new(dota.CEntityMessagePlayJingle) },
137: func() proto.Message { return new(dota.CEntityMessageScreenOverlay) },
138: func() proto.Message { return new(dota.CEntityMessageRemoveAllDecals) },
139: func() proto.Message { return new(dota.CEntityMessagePropagateForce) },
140: func() proto.Message { return new(dota.CEntityMessageDoSpark) },
141: func() proto.Message { return new(dota.CEntityMessageFixAngle) },
142: func() proto.Message { return new(dota.CUserMessageCloseCaptionPlaceholder) },
143: func() proto.Message { return new(dota.CUserMessageCameraTransition) },
144: func() proto.Message { return new(dota.CUserMessageAudioParameter) },
200: func() proto.Message { return new(dota.CMsgVDebugGameSessionIDEvent) },
201: func() proto.Message { return new(dota.CMsgPlaceDecalEvent) },
202: func() proto.Message { return new(dota.CMsgClearWorldDecalsEvent) },
203: func() proto.Message { return new(dota.CMsgClearEntityDecalsEvent) },
204: func() proto.Message { return new(dota.CMsgClearDecalsForSkeletonInstanceEvent) },
205: func() proto.Message { return new(dota.CMsgSource1LegacyGameEventList) },
206: func() proto.Message { return new(dota.CMsgSource1LegacyListenEvents) },
207: func() proto.Message { return new(dota.CMsgSource1LegacyGameEvent) },
208: func() proto.Message { return new(dota.CMsgSosStartSoundEvent) },
209: func() proto.Message { return new(dota.CMsgSosStopSoundEvent) },
210: func() proto.Message { return new(dota.CMsgSosSetSoundEventParams) },
211: func() proto.Message { return new(dota.CMsgSosSetLibraryStackFields) },
212: func() proto.Message { return new(dota.CMsgSosStopSoundEventHash) },
465: func() proto.Message { return new(dota.CDOTAUserMsg_AIDebugLine) },
466: func() proto.Message { return new(dota.CDOTAUserMsg_ChatEvent) },
467: func() proto.Message { return new(dota.CDOTAUserMsg_CombatHeroPositions) },
470: func() proto.Message { return new(dota.CDOTAUserMsg_CombatLogShowDeath) },
471: func() proto.Message { return new(dota.CDOTAUserMsg_CreateLinearProjectile) },
472: func() proto.Message { return new(dota.CDOTAUserMsg_DestroyLinearProjectile) },
473: func() proto.Message { return new(dota.CDOTAUserMsg_DodgeTrackingProjectiles) },
474: func() proto.Message { return new(dota.CDOTAUserMsg_GlobalLightColor) },
475: func() proto.Message { return new(dota.CDOTAUserMsg_GlobalLightDirection) },
476: func() proto.Message { return new(dota.CDOTAUserMsg_InvalidCommand) },
477: func() proto.Message { return new(dota.CDOTAUserMsg_LocationPing) },
478: func() proto.Message { return new(dota.CDOTAUserMsg_MapLine) },
479: func() proto.Message { return new(dota.CDOTAUserMsg_MiniKillCamInfo) },
480: func() proto.Message { return new(dota.CDOTAUserMsg_MinimapDebugPoint) },
481: func() proto.Message { return new(dota.CDOTAUserMsg_MinimapEvent) },
482: func() proto.Message { return new(dota.CDOTAUserMsg_NevermoreRequiem) },
483: func() proto.Message { return new(dota.CDOTAUserMsg_OverheadEvent) },
484: func() proto.Message { return new(dota.CDOTAUserMsg_SetNextAutobuyItem) },
485: func() proto.Message { return new(dota.CDOTAUserMsg_SharedCooldown) },
486: func() proto.Message { return new(dota.CDOTAUserMsg_SpectatorPlayerClick) },
487: func() proto.Message { return new(dota.CDOTAUserMsg_TutorialTipInfo) },
488: func() proto.Message { return new(dota.CDOTAUserMsg_UnitEvent) },
489: func() proto.Message { return new(dota.CDOTAUserMsg_ParticleManager) },
490: func() proto.Message { return new(dota.CDOTAUserMsg_BotChat) },
491: func() proto.Message { return new(dota.CDOTAUserMsg_HudError) },
492: func() proto.Message { return new(dota.CDOTAUserMsg_ItemPurchased) },
493: func() proto.Message { return new(dota.CDOTAUserMsg_Ping) },
494: func() proto.Message { return new(dota.CDOTAUserMsg_ItemFound) },
496: func() proto.Message { return new(dota.CDOTAUserMsg_SwapVerify) },
497: func() proto.Message { return new(dota.CDOTAUserMsg_WorldLine) },
499: func() proto.Message { return new(dota.CDOTAUserMsg_ItemAlert) },
500: func() proto.Message { return new(dota.CDOTAUserMsg_HalloweenDrops) },
501: func() proto.Message { return new(dota.CDOTAUserMsg_ChatWheel) },
502: func() proto.Message { return new(dota.CDOTAUserMsg_ReceivedXmasGift) },
503: func() proto.Message { return new(dota.CDOTAUserMsg_UpdateSharedContent) },
504: func() proto.Message { return new(dota.CDOTAUserMsg_TutorialRequestExp) },
505: func() proto.Message { return new(dota.CDOTAUserMsg_TutorialPingMinimap) },
506: func() proto.Message { return new(dota.CDOTAUserMsg_GamerulesStateChanged) },
507: func() proto.Message { return new(dota.CDOTAUserMsg_ShowSurvey) },
508: func() proto.Message { return new(dota.CDOTAUserMsg_TutorialFade) },
509: func() proto.Message { return new(dota.CDOTAUserMsg_AddQuestLogEntry) },
510: func() proto.Message { return new(dota.CDOTAUserMsg_SendStatPopup) },
511: func() proto.Message { return new(dota.CDOTAUserMsg_TutorialFinish) },
512: func() proto.Message { return new(dota.CDOTAUserMsg_SendRoshanPopup) },
513: func() proto.Message { return new(dota.CDOTAUserMsg_SendGenericToolTip) },
514: func() proto.Message { return new(dota.CDOTAUserMsg_SendFinalGold) },
515: func() proto.Message { return new(dota.CDOTAUserMsg_CustomMsg) },
516: func() proto.Message { return new(dota.CDOTAUserMsg_CoachHUDPing) },
517: func() proto.Message { return new(dota.CDOTAUserMsg_ClientLoadGridNav) },
518: func() proto.Message { return new(dota.CDOTAUserMsg_TE_Projectile) },
519: func() proto.Message { return new(dota.CDOTAUserMsg_TE_ProjectileLoc) },
520: func() proto.Message { return new(dota.CDOTAUserMsg_TE_DotaBloodImpact) },
521: func() proto.Message { return new(dota.CDOTAUserMsg_TE_UnitAnimation) },
522: func() proto.Message { return new(dota.CDOTAUserMsg_TE_UnitAnimationEnd) },
523: func() proto.Message { return new(dota.CDOTAUserMsg_AbilityPing) },
524: func() proto.Message { return new(dota.CDOTAUserMsg_ShowGenericPopup) },
525: func() proto.Message { return new(dota.CDOTAUserMsg_VoteStart) },
526: func() proto.Message { return new(dota.CDOTAUserMsg_VoteUpdate) },
527: func() proto.Message { return new(dota.CDOTAUserMsg_VoteEnd) },
528: func() proto.Message { return new(dota.CDOTAUserMsg_BoosterState) },
529: func() proto.Message { return new(dota.CDOTAUserMsg_WillPurchaseAlert) },
530: func() proto.Message { return new(dota.CDOTAUserMsg_TutorialMinimapPosition) },
531: func() proto.Message { return new(dota.CDOTAUserMsg_PlayerMMR) },
532: func() proto.Message { return new(dota.CDOTAUserMsg_AbilitySteal) },
533: func() proto.Message { return new(dota.CDOTAUserMsg_CourierKilledAlert) },
534: func() proto.Message { return new(dota.CDOTAUserMsg_EnemyItemAlert) },
535: func() proto.Message { return new(dota.CDOTAUserMsg_StatsMatchDetails) },
536: func() proto.Message { return new(dota.CDOTAUserMsg_MiniTaunt) },
537: func() proto.Message { return new(dota.CDOTAUserMsg_BuyBackStateAlert) },
538: func() proto.Message { return new(dota.CDOTAUserMsg_SpeechBubble) },
539: func() proto.Message { return new(dota.CDOTAUserMsg_CustomHeaderMessage) },
540: func() proto.Message { return new(dota.CDOTAUserMsg_QuickBuyAlert) },
542: func() proto.Message { return new(dota.CDOTAUserMsg_PredictionResult) },
543: func() proto.Message { return new(dota.CDOTAUserMsg_ModifierAlert) },
544: func() proto.Message { return new(dota.CDOTAUserMsg_HPManaAlert) },
545: func() proto.Message { return new(dota.CDOTAUserMsg_GlyphAlert) },
546: func() proto.Message { return new(dota.CDOTAUserMsg_BeastChat) },
547: func() proto.Message { return new(dota.CDOTAUserMsg_SpectatorPlayerUnitOrders) },
548: func() proto.Message { return new(dota.CDOTAUserMsg_CustomHudElement_Create) },
549: func() proto.Message { return new(dota.CDOTAUserMsg_CustomHudElement_Modify) },
550: func() proto.Message { return new(dota.CDOTAUserMsg_CustomHudElement_Destroy) },
551: func() proto.Message { return new(dota.CDOTAUserMsg_CompendiumState) },
552: func() proto.Message { return new(dota.CDOTAUserMsg_ProjectionAbility) },
553: func() proto.Message { return new(dota.CDOTAUserMsg_ProjectionEvent) },
555: func() proto.Message { return new(dota.CDOTAUserMsg_XPAlert) },
556: func() proto.Message { return new(dota.CDOTAUserMsg_UpdateQuestProgress) },
559: func() proto.Message { return new(dota.CDOTAUserMsg_QuestStatus) },
}

@ -1,6 +1,7 @@
package main
//go:generate ./mkprotos
//go:generate go run ./gen/main.go ./dota
import (
"compress/bzip2"

Loading…
Cancel
Save