feat: game integration system
Receive real-time events from games (CS2, Dota 2, LoL, etc.) and drive LED effects through the existing color strip and value source pipelines. Core: - GameEventBus (thread-safe pub/sub) with standardized 23-type event vocabulary - GameAdapter ABC + AdapterRegistry + MappingAdapter (YAML-driven) - Built-in adapters: CS2 GSI, Dota 2 GSI, LoL Live Client, Generic Webhook - Community YAML adapters: Minecraft, Valorant, Rocket League - GameEventColorStripStream with 5 effects (flash/pulse/sweep/color_shift/breathing) - GameEventValueSource with EMA smoothing and timeout - 4 built-in effect presets (FPS Combat, MOBA Health, Racing, Generic Alert) - Auto-setup for Valve GSI games (Steam path detection, cfg file writing) - Demo capture engine exposed to non-demo mode Frontend: - Game tab in Streams tree navigation with integration cards - Game integration editor modal with adapter picker, config fields, event mappings - game_event source type in CSS and ValueSource editors - Setup instructions overlay (markdown rendered) - Live event monitor and connection test API: - Full CRUD for game integrations - Event ingestion endpoint (adapter-level auth) - Adapter metadata, presets, auto-setup, status/diagnostics endpoints
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
/* Automation condition pills — constrain to card width */
|
||||
/* Automation rule pills — constrain to card width */
|
||||
[data-automation-id] .card-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -41,8 +41,8 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Automation condition editor rows */
|
||||
.automation-condition-row {
|
||||
/* Automation rule editor rows */
|
||||
.automation-rule-row {
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
@@ -50,19 +50,19 @@
|
||||
background: var(--bg-secondary, var(--bg-color));
|
||||
}
|
||||
|
||||
.condition-header {
|
||||
.rule-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.condition-type-label {
|
||||
.rule-type-label {
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.condition-type-select {
|
||||
.rule-type-select {
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
padding: 2px 6px;
|
||||
@@ -72,13 +72,13 @@
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.condition-always-desc {
|
||||
.rule-hint-desc {
|
||||
display: block;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.btn-remove-condition {
|
||||
.btn-remove-rule {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--danger-color, #dc3545);
|
||||
@@ -88,22 +88,22 @@
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
|
||||
.btn-remove-condition:hover {
|
||||
.btn-remove-rule:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.btn-remove-condition .icon {
|
||||
.btn-remove-rule .icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.condition-fields {
|
||||
.rule-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.condition-field label {
|
||||
.rule-field label {
|
||||
display: block;
|
||||
font-size: 0.85rem;
|
||||
margin-bottom: 3px;
|
||||
@@ -202,8 +202,8 @@
|
||||
}
|
||||
|
||||
|
||||
.condition-field select,
|
||||
.condition-field textarea {
|
||||
.rule-field select,
|
||||
.rule-field textarea {
|
||||
width: 100%;
|
||||
padding: 6px 8px;
|
||||
border: 1px solid var(--border-color);
|
||||
@@ -214,12 +214,12 @@
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.condition-apps {
|
||||
.rule-apps {
|
||||
resize: vertical;
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.condition-apps-header {
|
||||
.rule-apps-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user