From bad1f2570ba6d4d0626614ea9ab2b3af0a0640ca Mon Sep 17 00:00:00 2001 From: Merlin Date: Sat, 11 Jul 2026 03:08:25 +0800 Subject: [PATCH] init: cs player_status CDK demo --- .../event_detector.cpython-314.pyc | Bin 0 -> 2439 bytes logic/__pycache__/events.cpython-314.pyc | Bin 0 -> 3409 bytes logic/__pycache__/parser.cpython-314.pyc | Bin 0 -> 1115 bytes .../__pycache__/state_manager.cpython-314.pyc | Bin 0 -> 927 bytes logic/event_detector.py | 106 ++++++++++++++++++ logic/events.py | 47 ++++++++ logic/parser.py | 44 ++++++++ logic/state_manager.py | 21 ++++ main.py | 54 +++++++++ 9 files changed, 272 insertions(+) create mode 100644 logic/__pycache__/event_detector.cpython-314.pyc create mode 100644 logic/__pycache__/events.cpython-314.pyc create mode 100644 logic/__pycache__/parser.cpython-314.pyc create mode 100644 logic/__pycache__/state_manager.cpython-314.pyc create mode 100644 logic/event_detector.py create mode 100644 logic/events.py create mode 100644 logic/parser.py create mode 100644 logic/state_manager.py create mode 100644 main.py diff --git a/logic/__pycache__/event_detector.cpython-314.pyc b/logic/__pycache__/event_detector.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..987844bf9d79594b8ed346e45d4f31c5bdc1037f GIT binary patch literal 2439 zcma)8&u<$=6rT0k>mR#o$F6@Qaf0I#q8Qppt%4Mx3QCnW32jPhA%{bnWn*t_myK<9 zH$_Msa>GKAAW5qjF66)gE{HSY(ElMmSfe0CLL87dL~>C%@@95t?Wl5K4>RxE_r7o5 zo0)y~8(}$w;Q8z3gGWCF5c-_}_IMqmdjpIew2t!J5?bUeE<BR&GsPL{zXrM|j zMjW8xbycK+D!mxF;9W;^PY^0yMraHbe1JX#l%|MZaqb1%Q!;1KnvdaG$6#w_(CPm16~cU3v#_8x8d|M{L-U$yRcOP(;=H=0mNgrM?hq~8 zmTkLMvSIKRsN1GQP1kW3R&ywe&WaS~BG_wc`X=VU!7l2?!9|!O|O@$#Wjs|W~Jn`=9$K4Sg-+((?VI(p0VGO&)a+kjd%y0MxssO zG#Wol?WJ17$I;78p+nHVi;^RU<-KyNdYqhYiXDRX&!IuSc`DJ{cN4ke>4%ISc_( zZ1q7~cy9D)z!efcDw=?uTpaal&-~f4ncfAta5o#c9_)-ic@X++j47Y|33YNc1DRpY!8@ zqSVwaO;K=2QMT%(ZJpSXqI|Ng>W(L(D4SKowDf9CtJM|7Aiw`Op(v)MTGgVWT9#4W z*tRqis8K~J!nbCYszs})>AIr89|^hdCD6!k`Ay?B7!A_M=|BvVG?;(Bfcy1A_=xi* z&kz}nX%=%oCt!aCK4iVRLBBifqZir!{3L46&`WLF!a2gEbg~!@+^{Qr+aL{)WMPiN baK>{S_Zv$6frd}e=nJ99amg+sBjx@JEnw@c literal 0 HcmV?d00001 diff --git a/logic/__pycache__/events.cpython-314.pyc b/logic/__pycache__/events.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2848674de37bf34ef671a0152783670dc3ad4dc GIT binary patch literal 3409 zcmb_e-;diw5T3P@ob&r~=_S>1Tvei?hH?ig6+-1y(duXmMG^H0-|dP zG#8;7qQwN7kI)jLmdT7@-@8HWO$mLN6e?nLx{W zs{`Hk8)B!+f@0qkrsbHvZ$*5`zlcMae2haA*?t0o>B!|#PN*&L;4ys0bk+t(6FFTG z`Ntp%x{533g2p}b)b4pgx6S^GubxYUvI#Y=!bdbi;r zJ7J%|BlZJ)spyR6bYP^sp@M<}w@u%3M=Vf%!MjROIQICdDT1nD$UXE2mM{#TCVy}i zT=|T__JI)|MqPj7@MFAM$j9r1)5>F$N;WYGK^ENKXm9Gv-~nNod~HL#_@pr z!Wp=>>ml4&NOC-MEp%<-POzwfWtc+n!H+{>`{B&lUM<^k3}eK26|?)q@K?NsmeaE$ zjjVSKM_BJGcnN%Cie%JVOVztZjIB;=PStX116_qz=w5Cv)HK{3@gKYwPa9K7qp$`U zx!oq-_4oxEZ=+cx>JmB0$dLDGBtyuRk)cW|L*)bW)O>2M(5VfrGEZEp5|2AIz$v1DbSoYa>ZzyKJ}9pA`5M#Ayl1F>%f+w2Bibr z6ep4&F2x$<`6i{HDBdP>k<1nunh+K!kNQV6Btv>n=-~ebuX9>BgZ#02mN&Lms*I(( z*eAm(|9?jdRm?v(ouSRC&AnT~_B?k?K}k@ilfH*JI2jo-myBF7ik3;X6_czQ7UcF9 zRO8nu$G`NU_b?|T#iRF0C=Iz{d6!GGlPXQ|&XBt+dA|6kRAIUxty#vH9y=7BNsrHI zCK(wr*MnR!UY6<6iRn?1^`y&jlhTsu(9K*9a>ddvm*Z->91jMLvl2O`?JoZluIOjc zWtKXo%T?NKCSCSvCK(wr*M(de3EE91sCpkij{Fl(tdykUNwjJfqPAis#K_vktuDM4 z>Ko_1Y_Eme#2p!0fzP=kSFc+M%CoOc+vh6Hksm7ZB`nXQZ0534$+jV%5qV;zDsuUF zdkM7t@DuA6zl-ZJynF@iSY?d;0hh-GP|ANPjMc~Zl~$jqI2_AiDzHuw>$8aUu@)^= iB%nA0iZftojzq-Ld;n|TJ=v9RaMGhMX4o=nyYaF1|7In zrh4^cdveCC{X8tzEw$98-H_Z5(1QdLMW!clyw5$q_dO21u)UHO0U6UrA5Xq#0QeP( zcu-ftLL$KcsGtHopi)(!(Cyd@kvrrfxnS{|tPVf}9Nu(8f(#YZ!5)1XJ5+;O%1}2L zTBTDeWv;2ERp`B|{Z*hcDLXL&)td+hSo`eu%p~RWEy~ZzA!o(9*vC)+Rs-9Z)Z|* zbTB*^epgq5ze=KxjL8DV)-zFZ@J~zReX7KF8$w4O6~aa)?BK@xx2os1kdgk#bC82 zaRI2Y+=3hyd{C(9_&)%u5Q)lU!u)f~*83)Wfx<68dNbiqB*;({^_SkJxQP7+GE~#5 literal 0 HcmV?d00001 diff --git a/logic/__pycache__/state_manager.cpython-314.pyc b/logic/__pycache__/state_manager.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..19d3a63bf6ae1b2fc398121883a867534a9e262c GIT binary patch literal 927 zcmZuvOK;Oa5T3R3Fm2NGNh|7w@LnY9xXB<3(Xo}KTTZ)bdSEI$HhosAcJKMBAO^)awi zKj>YNoGMaAD}Gq_+=@_5X(Q>n)_flslzM?D zDUD`^1+5LzCOH)IlkPrv{K2^BE8Ne&mg^} z^DG`w)@^al0vYL{Ulr;dD=UlKP*<5&vx>8drv4dAl2lmn3|$*KqmxGuKG(nQf7$}DW0ezJMEc|N*$VJ;tUCF#!C++g~@{tXU04q zMKYd7SF#MXlfY>(+{p-~jj-DCRh*;rZOifdHw8*-9v9O00v3dna{C=*65j&L=>R0^z5#ReOMbgDf vV=QfU0bL?o)s`$0m!CqCi-&03OXT0@^H>ry6)@=Pgpf;ZnwUL67X$tPEV#;X literal 0 HcmV?d00001 diff --git a/logic/event_detector.py b/logic/event_detector.py new file mode 100644 index 0000000..9a41c72 --- /dev/null +++ b/logic/event_detector.py @@ -0,0 +1,106 @@ +from hashlib import new + +from logic import events +from logic.events import * + + +class EventDetector: + + + def detect(self, old, new): + + events=[] + + old_hp = old.get("health") + new_hp = new.get("health") + old_flashes = old.get("flashed") + new_flashes = new.get("flashed") + old_burning = old.get("burning") + new_burning = new.get("burning") + old_kills = old.get("kills") + new_kills = new.get("kills") + old_headshots = old.get("headshots") + new_headshots = new.get("headshots") + + + # 死亡 + if ( + old_hp > 0 + and new_hp == 0 + ): + events.append( + DeathEvent() + ) + + # 受伤 + if new_hp < old_hp: + + damage = old_hp-new_hp + + if damage >= 50: + events.append( + DamageEvent( + damage + ) + ) + + + events.append( + DamageEvent( + old_hp - new_hp + ) + ) + + + + + + # 闪光 + if new_flashes > old_flashes: + events.append( + FlashEvent( + new_flashes + ) + ) + elif new_flashes < old_flashes: + events.append( + FlashEndEvent() + ) + + # 燃烧 + if old_burning == 0 and new_burning > 0: + + events.append( + BurnEvent( + new_burning + ) + ) + # 燃烧结束 + elif old_burning > 0 and new_burning == 0: + + events.append( + BurnEndEvent() + ) + + + # 击杀 + if new_kills > old_kills: + + events.append( + KillEvent( + new_kills + ) + ) + + + # 爆头 + if new_headshots > old_headshots: + + events.append( + HeadshotEvent( + new_headshots + ) + ) + + + return events \ No newline at end of file diff --git a/logic/events.py b/logic/events.py new file mode 100644 index 0000000..b14dfa4 --- /dev/null +++ b/logic/events.py @@ -0,0 +1,47 @@ +from dataclasses import dataclass + + +@dataclass +class GameNotReadyEvent: + reason:str + +@dataclass +class GameReadyEvent: + reason:str + +@dataclass +class DamageEvent: + damage: int + + +@dataclass +class DeathEvent: + pass + + +@dataclass +class FlashEvent: + value: int + +@dataclass +class FlashEndEvent: + pass + +@dataclass +class BurnEvent: + value: int + + +@dataclass +class BurnEndEvent: + pass + + +@dataclass +class KillEvent: + kills: int + + +@dataclass +class HeadshotEvent: + headshots: int \ No newline at end of file diff --git a/logic/parser.py b/logic/parser.py new file mode 100644 index 0000000..91e260c --- /dev/null +++ b/logic/parser.py @@ -0,0 +1,44 @@ +def parse_game_state(data): + + player = data.get("player", {}) + state = player.get("state", {}) + + return { + + "timestamp": + data.get("provider", {}) + .get("timestamp"), + + + "player":{ + "name": + player.get("name"), + + "team": + player.get("team"), + + "health": + state.get("health"), + + "armor": + state.get("armor"), + + "helmet": + state.get("helmet"), + + "flashed": + state.get("flashed"), + + "smoked": + state.get("smoked"), + + "burning": + state.get("burning"), + + "kills": + state.get("round_kills"), + + "headshots": + state.get("round_killhs") + } + } \ No newline at end of file diff --git a/logic/state_manager.py b/logic/state_manager.py new file mode 100644 index 0000000..4c5e65a --- /dev/null +++ b/logic/state_manager.py @@ -0,0 +1,21 @@ +class StateManager: + + def __init__(self): + self.previous = None + + + def update(self, current): + + if current is None or current.get("health") is None: + return None, None + + # 第一次收到有效数据,只记录,不触发事件 + if self.previous is None: + self.previous = current + return None, None + + old = self.previous + + self.previous = current + + return old, current \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..e4cc527 --- /dev/null +++ b/main.py @@ -0,0 +1,54 @@ +from flask import Flask,request + +from logic.parser import parse_game_state +from logic.state_manager import StateManager +from logic.event_detector import EventDetector + + +app=Flask(__name__) + + +manager=StateManager() + +detector=EventDetector() + + + +@app.post("/") +def receive(): + + + data=request.json + + + state=parse_game_state(data) + + + old,new=manager.update( + state["player"] + ) + + if old is None or new is None: + return "OK" + + + events=detector.detect( + old, + new + ) + + + for event in events: + + print(event) + + + + return "OK" + + + +app.run( + host="127.0.0.1", + port=3000 +) \ No newline at end of file