Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ All commands follow a `:RESOURCE:ACTION:` naming convention. New commands must u
| Command | Buffer | Purpose |
|---------|--------|---------|
| `:EVENT:GENERAL:` | 1,000 | General gameplay event |
| `:EVENT:SECTOR:` | 1,000 | Sector state change (captured/contested/capturedFlag) |
| `:EVENT:SECTOR:` | 1,000 | Sector state change (captured/contested) |
| `:EVENT:ENDMISSION:` | 100 | End-of-mission event with side and message |
| `:EVENT:CHAT:` | 1,000 | Chat message |
| `:EVENT:RADIO:` | 1,000 | Radio transmission |
Expand Down
14 changes: 9 additions & 5 deletions internal/parser/parse_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func (p *Parser) ParseGeneralEvent(data []string) (core.GeneralEvent, error) {

// ParseSectorEvent parses sector state change events.
// Handles: captured, contested.
// Args: [frame, type, objectType, unitName, side, posX?, posY?, posZ?]
// Args: [frame, type, objectType, unitName, side, color, posX?, posY?, posZ?]
func (p *Parser) ParseSectorEvent(data []string) (core.SectorEvent, error) {
var event core.SectorEvent

Expand All @@ -212,16 +212,20 @@ func (p *Parser) ParseSectorEvent(data []string) (core.SectorEvent, error) {
event.Side = data[4]
}

if len(data) >= 8 {
event.PosX, err = strconv.ParseFloat(data[5], 64)
if len(data) >= 6 {
event.Color = data[5]
}

if len(data) >= 9 {
event.PosX, err = strconv.ParseFloat(data[6], 64)
if err != nil {
return event, fmt.Errorf("invalid position X for sector event: %w", err)
}
event.PosY, err = strconv.ParseFloat(data[6], 64)
event.PosY, err = strconv.ParseFloat(data[7], 64)
if err != nil {
return event, fmt.Errorf("invalid position Y for sector event: %w", err)
}
event.PosZ, err = strconv.ParseFloat(data[7], 64)
event.PosZ, err = strconv.ParseFloat(data[8], 64)
if err != nil {
return event, fmt.Errorf("invalid position Z for sector event: %w", err)
}
Expand Down
22 changes: 13 additions & 9 deletions internal/parser/parse_events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,46 +537,50 @@ func TestParseSectorEvent(t *testing.T) {
wantErr bool
}{
{
name: "captured with side and position",
input: []string{"200", "captured", "sector", "Sector Alpha", "WEST", "100.5", "200.3", "0"},
name: "captured with side, color and position",
input: []string{"200", "captured", "sector", "Sector Alpha", "WEST", "#0000FF", "100.5", "200.3", "0"},
check: func(t *testing.T, e core.SectorEvent) {
assert.Equal(t, core.Frame(200), e.CaptureFrame)
assert.Equal(t, "captured", e.Name)
assert.Equal(t, "sector", e.ObjectType)
assert.Equal(t, "Sector Alpha", e.UnitName)
assert.Equal(t, "WEST", e.Side)
assert.Equal(t, "#0000FF", e.Color)
assert.InDelta(t, 100.5, e.PosX, 0.001)
assert.InDelta(t, 200.3, e.PosY, 0.001)
assert.InDelta(t, 0.0, e.PosZ, 0.001)
},
},
{
name: "contested with empty side",
input: []string{"300", "contested", "sector", "Sector,With,Commas", "", "50", "60", "0"},
name: "contested with empty side and color",
input: []string{"300", "contested", "sector", "Sector,With,Commas", "", "", "50", "60", "0"},
check: func(t *testing.T, e core.SectorEvent) {
assert.Equal(t, "contested", e.Name)
assert.Equal(t, "Sector,With,Commas", e.UnitName)
assert.Equal(t, "", e.Side)
assert.Equal(t, "", e.Color)
},
},
{
name: "captured without position",
input: []string{"200", "captured", "sector", "Sector Alpha", "WEST"},
input: []string{"200", "captured", "sector", "Sector Alpha", "WEST", ""},
check: func(t *testing.T, e core.SectorEvent) {
assert.Equal(t, "captured", e.Name)
assert.Equal(t, "Sector Alpha", e.UnitName)
assert.Equal(t, "WEST", e.Side)
assert.Equal(t, "", e.Color)
assert.Equal(t, 0.0, e.PosX)
assert.Equal(t, 0.0, e.PosY)
assert.Equal(t, 0.0, e.PosZ)
},
},
{
name: "minimal without side or position",
name: "minimal without side, color or position",
input: []string{"200", "captured", "sector", "Alpha"},
check: func(t *testing.T, e core.SectorEvent) {
assert.Equal(t, "captured", e.Name)
assert.Equal(t, "", e.Side)
assert.Equal(t, "", e.Color)
},
},
{
Expand All @@ -591,17 +595,17 @@ func TestParseSectorEvent(t *testing.T) {
},
{
name: "error: bad position X",
input: []string{"200", "captured", "sector", "Alpha", "WEST", "not_a_number", "200", "0"},
input: []string{"200", "captured", "sector", "Alpha", "WEST", "#FF0000", "not_a_number", "200", "0"},
wantErr: true,
},
{
name: "error: bad position Y",
input: []string{"200", "captured", "sector", "Alpha", "WEST", "100", "not_a_number", "0"},
input: []string{"200", "captured", "sector", "Alpha", "WEST", "#FF0000", "100", "not_a_number", "0"},
wantErr: true,
},
{
name: "error: bad position Z",
input: []string{"200", "captured", "sector", "Alpha", "WEST", "100", "200", "not_a_number"},
input: []string{"200", "captured", "sector", "Alpha", "WEST", "#FF0000", "100", "200", "not_a_number"},
wantErr: true,
},
}
Expand Down
4 changes: 2 additions & 2 deletions internal/storage/memory/export/v1/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,12 @@ func Build(data *MissionData) Export {
}

// Convert sector events
// Format: [frameNum, "captured"|"contested", [objectType, unitName, side, [x, y, z]]]
// Format: [frameNum, "captured"|"contested", [objectType, unitName, side, color, [x, y, z]]]
for _, evt := range data.SectorEvents {
export.Events = append(export.Events, []any{
frameToV1(evt.CaptureFrame),
evt.Name,
[]any{evt.ObjectType, evt.UnitName, evt.Side, []float64{evt.PosX, evt.PosY, evt.PosZ}},
[]any{evt.ObjectType, evt.UnitName, evt.Side, evt.Color, []float64{evt.PosX, evt.PosY, evt.PosZ}},
})
}

Expand Down
7 changes: 4 additions & 3 deletions internal/storage/memory/export/v1/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,8 @@ func TestBuildWithSectorEvents(t *testing.T) {
Vehicles: make(map[uint16]*VehicleRecord),
Markers: make(map[string]*MarkerRecord),
SectorEvents: []core.SectorEvent{
{CaptureFrame: 15, Name: "captured", ObjectType: "sector", UnitName: "Sector Alpha", Side: "WEST", PosX: 100.5, PosY: 200.3, PosZ: 0},
{CaptureFrame: 30, Name: "contested", ObjectType: "flag", UnitName: "Flag Bravo", Side: "", PosX: 300, PosY: 400, PosZ: 10},
{CaptureFrame: 15, Name: "captured", ObjectType: "sector", UnitName: "Sector Alpha", Side: "WEST", Color: "#0000FF", PosX: 100.5, PosY: 200.3, PosZ: 0},
{CaptureFrame: 30, Name: "contested", ObjectType: "sector", UnitName: "Sector Bravo", Side: "", PosX: 300, PosY: 400, PosZ: 10},
},
}

Expand All @@ -507,7 +507,8 @@ func TestBuildWithSectorEvents(t *testing.T) {
assert.Equal(t, "sector", payload0[0])
assert.Equal(t, "Sector Alpha", payload0[1])
assert.Equal(t, "WEST", payload0[2])
pos0 := payload0[3].([]float64)
assert.Equal(t, "#0000FF", payload0[3])
pos0 := payload0[4].([]float64)
assert.Equal(t, 100.5, pos0[0])
assert.Equal(t, 200.3, pos0[1])
assert.Equal(t, 0.0, pos0[2])
Expand Down
3 changes: 2 additions & 1 deletion internal/storage/memory/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func TestIntegrationFullExport(t *testing.T) {
CaptureFrame: 15, Name: "connected", Message: "Player1 connected", ExtraData: map[string]any{"uid": "12345"},
}))
require.NoError(t, b.RecordSectorEvent(&core.SectorEvent{
CaptureFrame: 8, Name: "captured", ObjectType: "sector", UnitName: "Sector Alpha", Side: "WEST", PosX: 100.5, PosY: 200.3, PosZ: 0,
CaptureFrame: 8, Name: "captured", ObjectType: "sector", UnitName: "Sector Alpha", Side: "WEST", Color: "#00FF00", PosX: 100.5, PosY: 200.3, PosZ: 0,
}))
require.NoError(t, b.RecordEndMissionEvent(&core.EndMissionEvent{
CaptureFrame: 25, Side: "WEST", Message: "BLUFOR wins",
Expand Down Expand Up @@ -168,6 +168,7 @@ func TestIntegrationFullExport(t *testing.T) {
assert.Equal(t, "sector", sectorPayload[0])
assert.Equal(t, "Sector Alpha", sectorPayload[1])
assert.Equal(t, "WEST", sectorPayload[2])
assert.Equal(t, "#00FF00", sectorPayload[3])

// General event at frame 15 (v1: 14)
assert.EqualValues(t, 14, export.Events[1][0])
Expand Down
5 changes: 3 additions & 2 deletions pkg/core/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ type SectorEvent struct {
Time time.Time
CaptureFrame Frame
Name string // "captured", "contested"
ObjectType string // "sector", etc.
UnitName string // name of the sector
ObjectType string // "sector", "flag", etc.
UnitName string // name of the sector or player
Side string // capturing side ("WEST", "EAST", etc.) or empty
Color string // hex color (e.g. "#FF0000") or empty
PosX float64
PosY float64
PosZ float64
Expand Down
Loading