fix(minecraft): dirty teabagging workaround
This commit is contained in:
@@ -23,6 +23,7 @@ export class MineflayerPerceptionCollector {
|
||||
|
||||
private lastStatsAt = 0
|
||||
private stats: Record<string, number> = {}
|
||||
private sneakingState: Map<string, boolean> = new Map()
|
||||
|
||||
constructor(
|
||||
private readonly deps: {
|
||||
@@ -47,6 +48,10 @@ export class MineflayerPerceptionCollector {
|
||||
if (dist === null || dist > this.deps.maxDistance)
|
||||
return
|
||||
|
||||
// Ignore self
|
||||
if (entity.username === this.bot?.bot.username)
|
||||
return
|
||||
|
||||
const entityId = this.entityId(entity)
|
||||
|
||||
const event: SightedEntityMovedEvent = {
|
||||
@@ -73,6 +78,10 @@ export class MineflayerPerceptionCollector {
|
||||
if (dist === null || dist > this.deps.maxDistance)
|
||||
return
|
||||
|
||||
// Ignore self
|
||||
if (entity.username === this.bot?.bot.username)
|
||||
return
|
||||
|
||||
const event: SightedArmSwingEvent = {
|
||||
modality: 'sighted',
|
||||
kind: 'arm_swing',
|
||||
@@ -95,16 +104,27 @@ export class MineflayerPerceptionCollector {
|
||||
if (!entity || entity.type !== 'player')
|
||||
return
|
||||
|
||||
// Ignore self
|
||||
if (entity.username === this.bot?.bot.username)
|
||||
return
|
||||
|
||||
const entityId = this.entityId(entity)
|
||||
const flags = entity?.metadata?.[0]
|
||||
// Bit 1 (0x02) is sneaking
|
||||
const isSneaking = typeof flags === 'number' ? !!(flags & 0x02) : false
|
||||
|
||||
// Check if state actually changed
|
||||
const lastState = this.sneakingState.get(entityId)
|
||||
if (lastState === isSneaking) {
|
||||
return
|
||||
}
|
||||
this.sneakingState.set(entityId, isSneaking)
|
||||
|
||||
const now = Date.now()
|
||||
const dist = this.distanceTo(entity)
|
||||
if (dist === null || dist > this.deps.maxDistance)
|
||||
return
|
||||
|
||||
const entityId = this.entityId(entity)
|
||||
|
||||
const flags = entity?.metadata?.[0]
|
||||
const sneaking = typeof flags === 'number' ? !!(flags & 0x02) : false
|
||||
|
||||
const event: SightedSneakToggleEvent = {
|
||||
modality: 'sighted',
|
||||
kind: 'sneak_toggle',
|
||||
@@ -113,12 +133,14 @@ export class MineflayerPerceptionCollector {
|
||||
displayName: entity?.username,
|
||||
distance: dist,
|
||||
hasLineOfSight: true,
|
||||
sneaking,
|
||||
sneaking: isSneaking,
|
||||
timestamp: now,
|
||||
source: 'minecraft',
|
||||
pos: entity?.position,
|
||||
}
|
||||
|
||||
this.deps.logger.withFields({ entity: entity.username, sneaking: isSneaking }).log('MineflayerPerceptionCollector: sneak_toggle')
|
||||
|
||||
this.deps.emitRaw(event)
|
||||
this.bumpStat('sighted.sneak_toggle')
|
||||
this.maybeLogStats()
|
||||
|
||||
@@ -3,6 +3,7 @@ export type PerceptionSignalType
|
||||
| 'entity_attention' // e.g. someone waving, teabagging
|
||||
| 'environmental_anomaly' // e.g. sudden loud sound
|
||||
| 'saliency_high' // generic high saliency event
|
||||
| 'social_gesture' // e.g. teabagging, waving
|
||||
|
||||
export interface PerceptionSignal {
|
||||
type: PerceptionSignalType
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { ReflexBehavior } from '../types/behavior'
|
||||
|
||||
export const teabagBehavior: ReflexBehavior = {
|
||||
id: 'teabag',
|
||||
modes: ['social', 'idle'],
|
||||
cooldownMs: 5000,
|
||||
|
||||
when: (ctx) => {
|
||||
// Check if we recently received a teabag signal
|
||||
// Check if we recently received a teabag signal
|
||||
if (ctx.social.lastGesture === 'teabag') {
|
||||
const now = Date.now()
|
||||
const signalAge = now - (ctx.social.lastGestureAt || 0)
|
||||
|
||||
// Only respond if signal is fresh (< 2s)
|
||||
return signalAge < 2000
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
score: () => {
|
||||
// Higher priority than LookAt (50)
|
||||
return 60
|
||||
},
|
||||
|
||||
run: async ({ bot }) => {
|
||||
// Perform rapid squats
|
||||
for (let i = 0; i < 4; i++) {
|
||||
bot.bot.setControlState('sneak', true)
|
||||
await new Promise(resolve => setTimeout(resolve, 150))
|
||||
bot.bot.setControlState('sneak', false)
|
||||
await new Promise(resolve => setTimeout(resolve, 150))
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -21,6 +21,8 @@ export interface ReflexSocialState {
|
||||
lastMessage: string | null
|
||||
lastMessageAt: number | null
|
||||
lastGreetingAtBySpeaker: Record<string, number>
|
||||
lastGesture: string | null
|
||||
lastGestureAt: number | null
|
||||
}
|
||||
|
||||
export interface ReflexThreatState {
|
||||
@@ -69,6 +71,8 @@ export class ReflexContext {
|
||||
lastMessage: null,
|
||||
lastMessageAt: null,
|
||||
lastGreetingAtBySpeaker: {},
|
||||
lastGesture: null,
|
||||
lastGestureAt: null,
|
||||
},
|
||||
threat: {
|
||||
threatScore: 0,
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { ReflexContextState } from './context'
|
||||
import { DebugService } from '../../debug'
|
||||
import { greetingBehavior } from './behaviors/greeting'
|
||||
import { lookAtBehavior } from './behaviors/look-at'
|
||||
import { teabagBehavior } from './behaviors/teabag'
|
||||
import { ReflexRuntime } from './runtime'
|
||||
|
||||
export class ReflexManager {
|
||||
@@ -27,6 +28,7 @@ export class ReflexManager {
|
||||
|
||||
this.runtime.registerBehavior(greetingBehavior)
|
||||
this.runtime.registerBehavior(lookAtBehavior)
|
||||
this.runtime.registerBehavior(teabagBehavior)
|
||||
}
|
||||
|
||||
public init(bot: MineflayerWithAgents): void {
|
||||
@@ -71,6 +73,13 @@ export class ReflexManager {
|
||||
lastSignalAt: now,
|
||||
})
|
||||
|
||||
if (signal.type === 'social_gesture') {
|
||||
this.runtime.getContext().updateSocial({
|
||||
lastGesture: (signal.metadata as any)?.gesture ?? 'unknown',
|
||||
lastGestureAt: now,
|
||||
})
|
||||
}
|
||||
|
||||
// If it's a chat message (simulated via signal for now, or direct?)
|
||||
// For now we rely on signal metadata or separate chat event.
|
||||
// Assuming 'signal:social:chat' or similar might exist later.
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
name: teabag-attention
|
||||
version: 1
|
||||
|
||||
trigger:
|
||||
modality: sighted
|
||||
kind: sneak_toggle
|
||||
where:
|
||||
entityType: player
|
||||
|
||||
accumulator:
|
||||
threshold: 4
|
||||
window: 2s
|
||||
mode: sliding
|
||||
|
||||
signal:
|
||||
type: social_gesture
|
||||
description: 'Player {{ displayName }} is teabagging (rapid sneaking)'
|
||||
confidence: 1.0
|
||||
metadata:
|
||||
gesture: teabag
|
||||
distance: '{{ distance }}'
|
||||
displayName: '{{ displayName }}'
|
||||
hasLineOfSight: '{{ hasLineOfSight }}'
|
||||
Reference in New Issue
Block a user