diff options
Diffstat (limited to 'packet/clc/gamedata.go')
| -rw-r--r-- | packet/clc/gamedata.go | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/packet/clc/gamedata.go b/packet/clc/gamedata.go new file mode 100644 index 0000000..7ee5890 --- /dev/null +++ b/packet/clc/gamedata.go @@ -0,0 +1,101 @@ +package clc + +import ( + "errors" + + "github.com/osm/quake/common/buffer" + "github.com/osm/quake/common/context" + "github.com/osm/quake/packet/command" + "github.com/osm/quake/packet/command/bad" + "github.com/osm/quake/packet/command/delta" + "github.com/osm/quake/packet/command/ftevoicechatc" + "github.com/osm/quake/packet/command/move" + "github.com/osm/quake/packet/command/mvdweapon" + "github.com/osm/quake/packet/command/nopc" + "github.com/osm/quake/packet/command/stringcmd" + "github.com/osm/quake/packet/command/tmove" + "github.com/osm/quake/packet/command/upload" + "github.com/osm/quake/protocol" + "github.com/osm/quake/protocol/fte" + "github.com/osm/quake/protocol/mvd" +) + +var ErrUnknownCommandType = errors.New("unknown command type") + +type GameData struct { + Seq uint32 + Ack uint32 + QPort uint16 + Commands []command.Command +} + +func (gd *GameData) Bytes() []byte { + buf := buffer.New() + + buf.PutUint32(gd.Seq) + buf.PutUint32(gd.Ack) + buf.PutUint16(gd.QPort) + + for _, c := range gd.Commands { + buf.PutBytes(c.Bytes()) + } + + return buf.Bytes() +} + +func parseGameData(ctx *context.Context, buf *buffer.Buffer) (*GameData, error) { + var err error + var pkg GameData + + if pkg.Seq, err = buf.GetUint32(); err != nil { + return nil, err + } + + if pkg.Ack, err = buf.GetUint32(); err != nil { + return nil, err + } + + if pkg.QPort, err = buf.GetUint16(); err != nil { + return nil, err + } + + var cmd command.Command + for buf.Off() < buf.Len() { + typ, err := buf.ReadByte() + if err != nil { + return nil, err + } + + switch protocol.CommandType(typ) { + case protocol.CLCBad: + cmd, err = bad.Parse(ctx, buf, protocol.CLCBad) + case protocol.CLCNOP: + cmd, err = nopc.Parse(ctx, buf) + case protocol.CLCDoubleMove: + case protocol.CLCMove: + cmd, err = move.Parse(ctx, buf) + case protocol.CLCStringCmd: + cmd, err = stringcmd.Parse(ctx, buf) + case protocol.CLCDelta: + cmd, err = delta.Parse(ctx, buf) + case protocol.CLCTMove: + cmd, err = tmove.Parse(ctx, buf) + case protocol.CLCUpload: + cmd, err = upload.Parse(ctx, buf) + case fte.CLCVoiceChat: + cmd, err = ftevoicechatc.Parse(ctx, buf) + case mvd.CLCWeapon: + cmd, err = mvdweapon.Parse(ctx, buf) + default: + return nil, ErrUnknownCommandType + } + + if err != nil { + return nil, err + } + + pkg.Commands = append(pkg.Commands, cmd) + } + + return &pkg, nil +} |
