Private
Public Access
1
0

better deploy
Some checks failed
Dynamic Branch Deploy / build-and-deploy (push) Has been cancelled

This commit is contained in:
Sebastian Unterschütz
2025-11-27 19:42:08 +01:00
parent df9c3e4b76
commit 0412168c4e
11 changed files with 322 additions and 117 deletions

View File

@@ -8,20 +8,19 @@ import (
"strconv"
)
func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[string]string) (bool, int, []ActiveObstacle, PowerUpState, int) {
// 1. State laden
func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[string]string) (bool, int, []ActiveObstacle, PowerUpState, int, int) {
posY := parseOr(vals["pos_y"], PlayerYBase)
velY := parseOr(vals["vel_y"], 0.0)
score := int(parseOr(vals["score"], 0))
ticksAlive := int(parseOr(vals["total_ticks"], 0))
rngStateVal, _ := strconv.ParseInt(vals["rng_state"], 10, 64)
// Powerups laden
nextSpawnTick := int(parseOr(vals["next_spawn_tick"], 0))
godLives := int(parseOr(vals["p_god_lives"], 0))
hasBat := vals["p_has_bat"] == "1"
bootTicks := int(parseOr(vals["p_boot_ticks"], 0))
// Anti-Cheat State
lastJumpDist := parseOr(vals["ac_last_dist"], 0.0)
suspicionScore := int(parseOr(vals["ac_suspicion"], 0))
@@ -34,12 +33,6 @@ func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[st
obstacles = []ActiveObstacle{}
}
// --- DEBUG: Chunk Info ---
if len(inputs) > 0 {
log.Printf("📦 [%s] Processing Chunk: %d Ticks, %d Inputs", sessionID, totalTicks, len(inputs))
}
// --- ANTI-CHEAT: Spam Check ---
jumpCount := 0
for _, inp := range inputs {
if inp.Act == "JUMP" {
@@ -48,35 +41,29 @@ func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[st
}
if jumpCount > 10 {
log.Printf("🤖 BOT-ALARM [%s]: Spammt Sprünge (%d)", sessionID, jumpCount)
return true, score, obstacles, PowerUpState{}, ticksAlive
return true, score, obstacles, PowerUpState{}, ticksAlive, nextSpawnTick
}
playerDead := false
// --- SIMULATION LOOP ---
for i := 0; i < totalTicks; i++ {
ticksAlive++
// 1. Speed (Zeitbasiert)
currentSpeed := BaseSpeed + (float64(ticksAlive)/3000.0)*0.5
if currentSpeed > 12.0 {
currentSpeed = 12.0
}
// 2. Powerups Timer
currentJumpPower := JumpPower
if bootTicks > 0 {
currentJumpPower = HighJumpPower
bootTicks--
}
// 3. Input Verarbeitung (MIT DEBUG LOG)
didJump := false
isCrouching := false
for _, inp := range inputs {
if inp.Tick == i {
log.Printf("🕹️ [%s] ACTION at Tick %d: %s", sessionID, ticksAlive, inp.Act)
if inp.Act == "JUMP" {
didJump = true
}
@@ -86,7 +73,6 @@ func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[st
}
}
// 4. Physik
isGrounded := posY >= PlayerYBase-1.0
currentHeight := PlayerHeight
if isCrouching {
@@ -99,7 +85,6 @@ func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[st
if didJump && isGrounded && !isCrouching {
velY = currentJumpPower
// Heuristik Anti-Cheat (Abstand messen)
var distToObs float64 = -1.0
for _, o := range obstacles {
if o.X > 50.0 {
@@ -130,9 +115,7 @@ func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[st
hitboxY = posY + (PlayerHeight - currentHeight)
}
// 5. Hindernisse & Kollision
nextObstacles := []ActiveObstacle{}
rightmostX := 0.0
for _, obs := range obstacles {
obs.X -= currentSpeed
@@ -141,13 +124,11 @@ func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[st
continue
}
// Passed Check
paddingX := 10.0
if obs.X+obs.Width-paddingX < 55.0 {
realRightEdge := obs.X + obs.Width - paddingX
if realRightEdge < 55.0 {
nextObstacles = append(nextObstacles, obs)
if obs.X+obs.Width > rightmostX {
rightmostX = obs.X + obs.Width
}
continue
}
@@ -195,19 +176,19 @@ func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[st
}
nextObstacles = append(nextObstacles, obs)
if obs.X+obs.Width > rightmostX {
rightmostX = obs.X + obs.Width
}
}
obstacles = nextObstacles
// 6. Spawning
if rightmostX < GameWidth-10.0 {
gap := float64(int(400.0 + rng.NextRange(0, 500)))
spawnX := rightmostX + gap
if spawnX < GameWidth {
spawnX = GameWidth
}
if nextSpawnTick == 0 {
nextSpawnTick = ticksAlive + 50
}
if ticksAlive >= nextSpawnTick {
gapPixel := 400 + int(rng.NextRange(0, 500))
ticksToWait := int(float64(gapPixel) / currentSpeed)
nextSpawnTick = ticksAlive + ticksToWait
spawnX := GameWidth + 50.0
isBossPhase := (ticksAlive % 1500) > 1200
var possibleDefs []ObstacleDef
@@ -261,7 +242,7 @@ func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[st
}
}
if suspicionScore > 10 {
if suspicionScore > 15 {
log.Printf("🤖 BOT-ALARM [%s]: Zu perfekte Sprünge (Heuristik)", sessionID)
playerDead = true
}
@@ -273,27 +254,27 @@ func simulateChunk(sessionID string, inputs []Input, totalTicks int, vals map[st
}
rdb.HSet(ctx, "session:"+sessionID, map[string]interface{}{
"score": score,
"total_ticks": ticksAlive,
"pos_y": fmt.Sprintf("%f", posY),
"vel_y": fmt.Sprintf("%f", velY),
"rng_state": rng.State,
"obstacles": string(obsJson),
"p_god_lives": godLives,
"p_has_bat": batStr,
"p_boot_ticks": bootTicks,
"ac_last_dist": fmt.Sprintf("%f", lastJumpDist),
"ac_suspicion": suspicionScore,
"score": score,
"total_ticks": ticksAlive,
"next_spawn_tick": nextSpawnTick,
"pos_y": fmt.Sprintf("%f", posY),
"vel_y": fmt.Sprintf("%f", velY),
"rng_state": rng.State,
"obstacles": string(obsJson),
"p_god_lives": godLives,
"p_has_bat": batStr,
"p_boot_ticks": bootTicks,
"ac_last_dist": fmt.Sprintf("%f", lastJumpDist),
"ac_suspicion": suspicionScore,
})
// Return PowerUp State
pState := PowerUpState{
GodLives: godLives,
HasBat: hasBat,
BootTicks: bootTicks,
}
return playerDead, score, obstacles, pState, ticksAlive
return playerDead, score, obstacles, pState, ticksAlive, nextSpawnTick
}
func parseOr(s string, def float64) float64 {