From 0080ce2710dbc85a611842624ef2185e07267f6e Mon Sep 17 00:00:00 2001 From: wr34k Date: Thu, 28 Jun 2018 10:00:12 +0200 Subject: [PATCH] First commit --- .gitignore | 2 + README.md | 0 __pycache__/fight.cpython-36.pyc | Bin 0 -> 6658 bytes __pycache__/fighter.cpython-36.pyc | Bin 0 -> 578 bytes __pycache__/ircCommands.cpython-36.pyc | Bin 0 -> 2164 bytes __pycache__/ircReload.cpython-36.pyc | Bin 0 -> 902 bytes __pycache__/log.cpython-36.pyc | Bin 0 -> 2874 bytes __pycache__/mircformat.cpython-36.pyc | Bin 0 -> 948 bytes admins | 1 + config.json | 215 +++++++++++++++++++++ fight.py | 248 +++++++++++++++++++++++++ fighter.py | 23 +++ irc.py | 202 ++++++++++++++++++++ ircCommands.py | 80 ++++++++ ircReload.py | 40 ++++ log.py | 77 ++++++++ mircformat.py | 24 +++ 17 files changed, 912 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 __pycache__/fight.cpython-36.pyc create mode 100644 __pycache__/fighter.cpython-36.pyc create mode 100644 __pycache__/ircCommands.cpython-36.pyc create mode 100644 __pycache__/ircReload.cpython-36.pyc create mode 100644 __pycache__/log.cpython-36.pyc create mode 100644 __pycache__/mircformat.cpython-36.pyc create mode 100644 admins create mode 100644 config.json create mode 100644 fight.py create mode 100644 fighter.py create mode 100644 irc.py create mode 100644 ircCommands.py create mode 100644 ircReload.py create mode 100644 log.py create mode 100644 mircformat.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f04cb2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# pyCache +__pycache__/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/__pycache__/fight.cpython-36.pyc b/__pycache__/fight.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ebfc573f56048e5ea0b73f93ae40cb400825ef3b GIT binary patch literal 6658 zcmbVR&2JmW72la%E|(NV(XuQ{vJ<|!|AU;{TmFQ-7AW9Tfdakw)ZcrvTv2k+7^Sc?v$Jo$ z-pB8~H@Y-EUEc6s{l)#~E$biF#Lq$dI-clN6v|SfZ*7XE5Y(1^*_2${OdqfV*QsB7vO?EBfYz#Hz+mgq+{JvZ<~&!QNLq16IQ zP>MARr5sv4d*34FU;^1ly>8g<#NGQr-AV2DKfRF_qPQIgsfV)@E26Z#7Q`*XjJiyn zDCn>10_Og!rOT)uKXYMyuo+zF2kq4h_w-ID*lXRtc!7tnZ0)69tJMv=ajR9LO?fCR z;nJT>s=WJ^F+oSrNBrmrM9s%|360o_g%bPn5A!1t%bqvH7AWWxjeB8MC{=2Q4?|=AC>X0bYLVwU!QR?WRtx|VK^u&g%&x7~0c`6+xdxfFc$DxcYhL&UX z#89k>*Kz)qh+WX(yRtW=-aRzZ!AN{lg+)jdwYzBTOP;4l(hg@2QG4SR>ZL|H^Pt_0 zyWv_ZlWwy7Ua;ps9Qk{LopUf*^X1YAB1&jgye+X&c+crrRBC#ESNygVX9~r1?gE?EC@%|WL3N%JUJHL z0dcN#Ht6YL;r#{;BfJw2@m5dJ9>va}{XgSR*l#yQg7x5@P#l zY?HA;XH6})uihqgkQ$c%)K@a-;I5n(^Nt4|d!k}{qADvnhYtqi9Hy<2teL|NGz^D#-@~*x)m!l zaVUGYdj;k6h-XE%eli_4p6x0j0Klx!NKYP7@2F)CnVh`6-j4llM0&3MFxZX#&B6WP zjpXE;%!SBr-*0#O?R)*;ihu6m=v?BQJMW*Xdq-4MFJj;N87fYp0Hh4MVS0l2N|UyD zmTb{XUs)fIFjPN>!9T<^#zR>VHIXbbhgZHuN;$?519Ob|8(zQ=Fme$r915u1()c~} zxCO->k=jBzbDC@4LSwI4BWHIDU!<~uD`5Mg1)kL>^j*Nj6IQBEH&S4Er|Y2G}h~@@&v`XgJ))ouM4s#&I((a7b9&BwjPt zG4HT~0z`N^TXB|Gq;))KIYh~4_n_+Feqmt^_pgPk1rJL`ieIASErkARj(-F(`QadjtLO~Y!fq0%TQ^}ZjOHYlv`maL=Ed-CZ08(4Y2tV~vlVE9cbfUu zjt(KzTx_Xp43~{3b<`jXjz}$?!9FshV-x-ab8^f>Ub>9GDu90uE}$l7rNez5>g0rx z9Y(!M`O2{ar6@ylFVdy1$~T63Xur+k~^1>nFMz;iR3hJ_medHnFKT3 zvKz?deH92>sP3En0Fdo&pKH!hFjE=T>gLOniSrI zz!>M``j$QqX6TD3GM8~+Uq?k#0)m-ctb#nlI1#&P$05GfX;ChM2I&#d!ty)fn!Iqz%7cb1Q{NjOeW0O z!yCDp0#PYMUab;G(#Gky4da9<_(^7^{mN^6K5{iM5WSN8NZJoa4@WcpgF)!W>wyV? z{PtSA8%D98f9=NWc=`S%B3<9|`@w3wq6tjuWn)vXquq2KU{urX4`8MdLiP2*PHa38 zBH2EC8w(}1yJ5_pYwX=!jDrbfBlQykTcz0UV{CYURU!&_Eui2TgiTdh7B5Iwj0Kld z=7J-?PQqi0xrs&=_QE9*&afCM8ajiP93#)}9NugoV|gSLVxpF_eIEEU8Tr_a=FFBJ zbb=_Nh&2X8q-9>dMXb#t9w0>=w-FHj7%Ll2k&d#5{a+sV5{M{)%MR;G4+r%C8PHQX z28kmGl>+SjUbezh?_ZU0UN}>VONQ>SIP_Ls zL=)wPu9E_gMY3%o`QBXXs@>Gx?1pHj-o5^yvq3%O)poy6xke{QrwCP5_Tt2FN-!RZ zEhd1kWIPnb6#8Wpsg3#cb$X=$Lcc`?*+E*M38JHRHk${E6y>y3J8u6D)LFK&BJd~g zKnL&QS&_*CV+qHD?^&W#6#zW+Q}j zFbATO@TEhP-%La77M&*$^nnJ%(nW=qyRN)n;dZl57vI)Su7)?*^32S}L z?-UZ#9#HcRzRq{R>yF3pKA0-o%k)#wRj}u(k&>F8vxd{dlA1nc%~=~3*8g|D<0^JM zlka%O>^S`6cx?*Ozm%HdKSxz@CZ|^(?;Y0zIGtHzSi~CMNo!QgXC_`88#-`|Q^VS2 zx_+3N*iRYzkovc329lus%kYmRP{S#Y;qt*A(UpUvh?BEsUs!oci4B2~#H&h=I8o_U z)vVbWsOaM3INa$BWp7MB$16QXyM}R(S@s9J9ItqSSH#F{#pBtElR9GS4<=6FVqWy9 zd1%y=CpgLTkzSh<%$fN(r(7_p$=W6U{r!zBM_~X-K7VTfr_CM-_hfz>_b0L5gRk=A zfzKp9l1}pZQF{~Lx|_jygv-%RpOSgM8~Sa(GuYh1RZ7sOI~Sz+Dp0-&=5RxD>!zmL zFUGT`YoIBS4@dfK^gdE3l9vz|-qL#*m9L4OdpoheihLH`o82hT$ZPkO_4hC!b-Ll| zpjlzCyO1@t9`C47$i~^<&xxiSfJ3 z)MDpLsqF-IzKhqiw1or4d$)E?z+$3D3Th@|%_VvzJZsigyE=+n#IqJJUq4~6_jw{Y zgCg~e;}3M|sbDn-72+E^-rQmU*6$GAbt(>!nSztlj(6kc6pP1jv{~X8bVp6&8i=BZ z`>Q^oJMp?%Bu7Er9&d(Q%mB2GfV_SK1O9|3+CpK;@%;$J6&}A;5NVX1r|SryCf` zWH{3q_rv8P2+qB2Qa(GD%h{xug}3M&i|8z}a~~T3gW+x|PCbpc6ztyWx3dIZUqKfu z$T%nbh&t%bs96NZ`?#CbA5#}yK%0VZYw2YF!jq*O3t$LXlBFEE{vFEoh(pYkAE2@O zEKq>*^*O#Y5k1QIaN9i2u<@1ps04o)!RY2mG{zSa#N&xOBGTt^2yWwI^IPwN$XNb^ zCnCkC$6nQ zJrif!nvSP0Q^A2Ug}<8YlGRlc<1}0C0Y|yTY_;)~a^i?YUV3;Y3kGl$Xu literal 0 HcmV?d00001 diff --git a/__pycache__/ircCommands.cpython-36.pyc b/__pycache__/ircCommands.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce75085088f0e036556e266e8d56f6152c0f8cc2 GIT binary patch literal 2164 zcmZt{O>f*pbiVu%XS3Oa&?cnsv9=ccvGV1Q-v)&IOO}=Z z{1NQxHULQ^ostMoHl;a>7$x5k$)$Knq)>dpBO&Pl89EmrO-4g%oc-+RxK8nUxfmdi zU{`klC=yXgA||P1FG<8(WuV59F5DgINgqyEu7KLWtUl4{<1){aLRKj%!i6X9$FQqw z02f0reii?dLJ+jzOaTjqH#J2@Z~oKQl9Lvg-0PH;2$4p3K}mE425y3 z*)*%IU&bwG^+cVS;20t|RdJfjp|4#KG$I9>aT1wlg%L%TPK=mWN*i%pR<+@Ib!0@M zk189Q7N8ezbb&x0?iFey)TdkY{MvF1x+g&_9N_(Br3Fe$XCk`0(@^P- z-G(jb0xDaI)+T)KZ9NZwccpG`LVl+@xYX_t(C>W>?t&+1-#af{rPcP2KiY3o=|GU4 zU0}JMZ}YwTclPf6@`B&HA0AB0(@>VDMVNo1v7Uxro9N(hT9z_CoF+%cpC(m}sWzg{ za%EOqURutJ+ITaaonUU=!&2u-J><3=G^SDy5MaqJrF%6!R_O#ZgZ?dGRi6MLv`2dk zHvg0gej9S%qXR0~4ZyZ6c7A=i7M66RSVXw+L_cjYJY6mZrUwmwf#m>+ZTN!e5DUFw z`c>mf3N7*q+h7OUWPwR%`Wf7XZ6Ol3Wh54alH%c#oC9*dw&{R$V_S)~r6BDTWH&9( zZFwyXDBjqYgNdvEhL=}B!#|d`0#?B{9Y1(O5A3U3AiMg8w)&QAZ^EEdJ_Cuh4r}f0 zO*qiEtj0BHd=E>pv#AeMGVaN~Ezfm(TgUS3T4P{Kbz{8IwZo?6;b_y~*iJ{KHKr!&ceg6mDv@WATh&QDucGVkNLMkc zDGTGa=lT6nS%=3;t5B;t(K0+M=Q=EBv$9Y{9i~YUR!X(hLj7Ead3mBf-XAiJ<)v={ z7`|sqyEXemG~0pdhXEDLXELeP2u79;QTihUXfMn@uunxnBBlKSDIEns(zU%sD@Uq6 zupSr>$6ukQ(R!uo7)|J0&^J-rHi8cj+(57cpc|ZRr>rB@w#x=$n*a=lmebfG@3fF! z1KJ+!>MH=)Is#fpFabkzfQ{wcvR@gL#s=yw1B literal 0 HcmV?d00001 diff --git a/__pycache__/ircReload.cpython-36.pyc b/__pycache__/ircReload.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd6504cc27def6289f82a9d2a550f13ee9518fc2 GIT binary patch literal 902 zcmZuv&2H2%5cW8~o2J!@pQ;s?rI$8nwJWtZgixib2ZU51N<|e8Q5t*I-R4hDin?jS zC2;38cm-a7ckmHTy>jHlc(a8fVav{B{LMGtjJ>zI>U{sU_wJ=e$PaR7;6K^NRSa=s zgh5Oa@Bx%fW9n0;G5sU)HLi1w87;Kxj2;uuyuk?Kfiwk=vydG{pd2_XTzj|dxuvM&&z3+N+XK1f=g>DM5revC~i_K=7qG9j9tdO@GRfy%rs26-$VPwq6NN% zwX0mdg1!pNa|sivM;YT1_!lDXBiFCTiY)~8RKF%%tx^NFR^feFve#Wx nJUv^KB-Rkq0gYTt({ds1&h|iY*w4B`pQ~0BN{kCOwYPo)1drho literal 0 HcmV?d00001 diff --git a/__pycache__/log.cpython-36.pyc b/__pycache__/log.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..709ad8fa23d74ce30b18cca3b85933f8b5fc3055 GIT binary patch literal 2874 zcmc&$ZBH9V5Wc-PpN$O$(pTDsL{(KsEu_J1;wnYF_#ghc`6NEY6^B3Jdxc^-WBgEL`p6ZDucLC*{= zuwz5t5;pX0>O0VPgbRI_`mRU`@7&-ikp}x2$1^_Av2`Nb@O?;aM@ob0W*9MUKyiX`UA|d{*T7oS5bFVh+MN z-=7_aGi=G|v@80~!ofs_bvAKdbC1i2C~GuCi)=SvlJ^->)in->+1jyioQ= z<(aQikJq>T>fXAtH}}`8DqY#xezXS@_mx*(ukGp<4Wfxm@)_(*QF~}i>ygDQjVEUH z2eR$Fc(k+UkLlJe7yZoux5FSJwef9$%luAqowVggFztWge52m@Wz2a|b6(Wk6*YH7 z&0SG*SJd1UHFrhLT@g5U;r!hNMUtRN5>!coE=f=(3ECt00$c~{athPe%_VfdiL+}(ti z3=E88W%JXNHG4`Cct}SI?9i9Ug~`9<59((rWTEuraX=1quyI+!`Ln z7zy!MKAoS-&(r9ol*L24hSRFkuRtRihCV{lbA>}scno)N1wA(0{@>5Wdw-Ls~)248@C3s`p znZZ2P&%&xpN!Uib;?lUYZFpnMD#4D2H|T(sjWc$}z-POv#;K5a9HR<)JTP8nerE&r z9J1t9;xRc?FqOG8TVXeReIi#^(F&Thjs7CK*oeAu5AKxS(!+MtsJG+Q zrO{+em*eQDJKVXl>#`MJv8~c03qK^b4c5wlIe+ zM_2=P=AJPI|2Zfs7wkZ>JAL!zB4j$zPyiG17Q!b8bXd`T;<43 zz*i4_#lio`O^F-3V7K1lC>4|mN99+b@-Ih!tIIA$3JFUb#ldO=lL#M_Sk!3RPtbU` zfDTN#_x71RcVI#~PKKZMrPyoQSL#{eLA6( zk=%kw!_xBw{DJAGkrn!al`Va>>^LX#sN2(JhO*#m(3i^y_YlShbXHkCjL-3ArUbI6r`Y{0t{8iAp;F_FoYW9aR>^S2OSGAj5>_q zFcfhFMzIKEI11x91`{|AlQ;oWI0+@3f@v(l3{Jx=&fx4dfjOKLH9X<^C(EsWjN+a@ zNU4(2=P7-W(wUTwU8w5fq69<2l7wXmuO+NVcq8Ghgm)6&3osi0 zvY>FKyvV5^=S5Hk>C4Jt)C()!(BH4@#b-fy?tNXV^p4_SKWn>ua-J4e55j)7KAmG3wUl(XaLs4vu65_b1F^W%f$zJz#Kz>z(@T@ES5zjk4^Sievtk$v{pjn-&ZPmHH_&bInb&!*e_9R!8h=cD262Sr#*y8P soJlO7gnSCgD*<`R{`XTdrXvQfMSI6#Fv#|gN$~vY&G6PT9U(*h0Hqt#lK=n! literal 0 HcmV?d00001 diff --git a/admins b/admins new file mode 100644 index 0000000..8e386b3 --- /dev/null +++ b/admins @@ -0,0 +1 @@ +*!*@*.sp0ns0r3d.sploit.sh diff --git a/config.json b/config.json new file mode 100644 index 0000000..35fd112 --- /dev/null +++ b/config.json @@ -0,0 +1,215 @@ +{ + "info": { + "lowhp": [ + "%defender% starts bleeding", + "%defender% is having trouble focusing", + "%defender% is stagging", + "%defender% seems wasted" + ], + "ground2stand": [ + "%attacker% gets back on its feet", + "%attacker% is standing up" + ], + "stand2ground": [ + "%defender% just fell to the ground", + "%defender% falls over" + ] + }, + + "moves": { + "stand": { + "kick": { + "high": { + "stand": { + "dmgidx": 40, + "mindmg": 20, + "fallchance": 5, + "blockidx": 40, + "text": [ + "%attacker% head kicks %defender%" + ] + }, + "ground": { + "dmgidx": 60, + "mindmg": 25, + "blockidx": 28, + "text": [ + "%attacker% stomps %defender% in the head!" + ] + } + }, + "middle": { + "stand": { + "dmgidx": 30, + "mindmg": 10, + "fallchance": 8, + "blockidx": 28, + "text": [ + "%attacker% middle kicks %defender%" + ] + }, + "ground": { + "dmgidx": 45, + "mindmg": 20, + "blockidx": 34, + "text": [ + "%attacker% stomps %defender% in the body!" + ] + } + }, + "low": { + "stand": { + "dmgidx": 23, + "mindmg": 5, + "fallchance": 15, + "blockidx": 35, + "text": [ + "%attacker% low kicks %defender%" + ] + }, + "ground": { + "dmgidx": 30, + "mindmg": 15, + "blockidx": 40, + "text": [ + "%attacker% kicks %defender%'s legs while %defender% is on the ground" + ] + } + } + }, + "punch": { + "high": { + "stand": { + "dmgidx": 30, + "mindmg": 10, + "fallchance": 2, + "blockidx": 30, + "text": [ + "%attacker% head punches %defender%" + ] + } + }, + "middle": { + "stand": { + "dmgidx": 20, + "mindmg": 5, + "fallchance": 4, + "blockidx": 15, + "text": [ + "%attacker% punches %defender% to the body" + ] + } + } + }, + "block": { + "high": { + "chance": 85, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + }, + "middle": { + "chance": 85, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + }, + "low": { + "chance": 80, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + } + } + }, + "ground": { + "standup": { + "stand": { + "chance": 30 + }, + "ground": { + "chance": 70 + } + }, + "kick": { + "high": { + "stand": { + "dmgidx": 30, + "mindmg": 10, + "fallchance": 8, + "blockidx": 40, + "text": [ + "%attacker% head kicks %defender% from the ground!" + ] + }, + "ground": { + "dmgidx": 40, + "mindmg": 23, + "blockidx": 55, + "text": [ + "%attacker% hit %defender% with huge kneel kicks to the head!" + ] + } + }, + "middle": { + "stand": { + "dmgidx": 20, + "mindmg": 5, + "fallchance": 5, + "blockidx": 40, + "text": [ + "%attacker% middle kicks %defender% from the ground!" + ] + }, + "ground": { + "dmgidx": 25, + "mindmg": 17, + "blockidx": 50, + "text": [ + "%attacker% hit %defender% with kneel kicks to the body" + ] + } + }, + "low": { + "stand": { + "dmgidx": 15, + "mindmg": 3, + "fallchance": 18, + "blockidx": 45, + "text": [ + "%attacker% low kicks %defender% from the ground!" + ] + }, + "ground": { + "dmgidx": 15, + "mindmg": 2, + "blockidx": 30, + "text": [ + "%attacker% hit %defender% with kneel kicks to the legs" + ] + } + } + }, + "block": { + "high": { + "chance": 90, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + }, + "middle": { + "chance": 90, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + }, + "low": { + "chance": 85, + "text": [ + "Good block from %defender% he managed to avoid the hit!" + ] + } + } + } + } +} diff --git a/fight.py b/fight.py new file mode 100644 index 0000000..400cbea --- /dev/null +++ b/fight.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python3 + +from fighter import Fighter +import random, json + +CONFIG_FILE = "./config.json" + +class Fight(object): + def __init__(self, IRC): + self.IRC = IRC + self.state = 'inactive' + self.fighters = [] + + self.get_config() + + def get_config(self): + with open(CONFIG_FILE, "r") as f: + self.config = json.loads(f.read()) + + def addFighter(self, nick): + self.state = 'waiting_fighter' + if nick in self.fighters: + self.IRC.privmsg(self.IRC.channel, "Hey {} you're already registered!".format(nick)) + return + else: + self.fighters += [nick] + + if len(self.fighters) == 2: + self.IRC.privmsg(self.IRC.channel, "Alright {}, {}, let's fight!".format(self.fighters[0], self.fighters[1])) + self.state = 'fighters_ready' + else: + self.IRC.privmsg(self.IRC.channel, "Waiting for 2nd fighter...") + + + def startFight(self): + self.state = 'starting_fight' + + self.fighters[0] = Fighter(self.fighters[0], self.IRC.mirc.RED) + self.fighters[1] = Fighter(self.fighters[1], self.IRC.mirc.BLUE) + + + # who start? + roll1 = roll2 = 0 + while roll1 == roll2: + roll1 = random.random() + roll2 = random.random() + + + if roll1 > roll2: + self.fighters[0].advantage = True + else: + self.fighters[1].advantage = True + + self.print_fighters_action() + + + def print_fighters_action(self): + self.state = 'waiting_fighters_action' + + for f in self.fighters: + self.IRC.privmsg(f.nick, "What is your next move?") + self.IRC.privmsg(f.nick, "Actions available: '{}'".format("', '".join(self.get_next_avail_action(f.nick)))) + + + def get_next_avail_action(self, nick): # TODO: fix this mess. + f = self.fighters[0] if self.fighters[0].nick == nick else self.fighters[1] + e = self.fighters[0] if self.fighters[1].nick == nick else self.fighters[1] + cmds = [] + for i in self.config['moves'][f.stance]: + if i == 'standup': + cmds += [i] + elif i == 'punch' and e.stance == 'ground': + pass + else: + for j in self.config['moves'][f.stance][i]: + cmds += ["{} {}".format(i, j)] + + return cmds + + def set_next_action(self, nick, action): + for f in self.fighters: + if f.nick == nick: + if f.nextAction is not None: + self.IRC.privmsg(nick, "You already chose your next move!") + return + + if " ".join(action) in self.get_next_avail_action(nick): + f.nextAction = action + self.IRC.privmsg(nick, "Next move set!") + else: + self.IRC.privmsg(nick, "Move not recognized") + + done = True + for f in self.fighters: + if f.nextAction is None: + done = False + + if done: + self.performNextTurn() + + + def getStatus(self, nick): + for f in self.fighters: + if f.nick == nick: + self.IRC.privmsg(nick, "Status for {} -> Current health: {} | Current stance: {} | Next action: {}".format(f.nick, f.hp, f.stance, f.nextAction)) + else: + self.IRC.privmsg(nick, "Status for {} -> Current health: {} | Current stance: {}".format(f.nick, f.hp, f.stance)) + + + + def fightOver(self): + winner = self.fighters[0] if self.fighters[1].hp <= 0 else self.fighters[1] + looser = self.fighters[0] if self.fighters[0].hp <= 0 else self.fighters[1] + + winner.wins += 1 + looser.looses += 1 + + self.shout("\x02\x0315Fight is over.") + self.shout("\x02\x03{}{}\x0f won the fight against \x02\x03{}{}\x0f with \x02\x0303{}\x0f hp left.".format(winner.colour, winner.nick, looser.colour, looser.nick, int(winner.hp))) + + self.state = 'inactive' + self.fighters = [] + + def performNextTurn(self): + self.state = 'processing_turn' + + self.attack() + + if self.state == 'fight_over': + self.fightOver() + return + + for f in self.fighters: + f.nextAction = None + + self.print_fighters_action() + + + + def get_next_move_data(self, f, e): + dmg = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['dmgidx'] + mindmg = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['mindmg'] + blockidx = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['blockidx'] + fallchance = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['fallchance'] \ + if 'fallchance' in self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance] \ + else 0 + standchance = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['standchance'] \ + if 'standchance' in self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance] \ + else 0 + + texts = self.config['moves'][f.stance][f.nextAction[0]][f.nextAction[1]][e.stance]['text'] + + return dmg, mindmg, blockidx, fallchance, standchance, texts + + def attack(self): + + roll1 = roll2 = 0 + while roll1 == roll2: + roll1 = random.random() + roll2 = random.random() + + + if self.fighters[0].advantage: + roll1 += 0.15 + else: + roll2 += 0.15 + + if roll1 > roll2: + attacker = self.fighters[0] + defender = self.fighters[1] + else: + attacker = self.fighters[1] + defender = self.fighters[0] + + if attacker.nextAction[0] == 'block' and defender.nextAction[0] != 'block': + tmp = attacker + attacker = defender + defender = tmp + elif attacker.nextAction[0] == 'block' and defender.nextAction[0] == 'block': + self.shout("Both fighters are trying to block at the same time, resulting in a completely retarded action...") + return + + attacker.advantage = True + defender.advantage = False + + if attacker.nextAction[0] == 'standup': + standchance = self.config['moves'][attacker.stance]['standup'][defender.stance]['chance'] + else: + dmg, mindmg, blockidx, fallchance, standchance, texts = self.get_next_move_data(attacker, defender) + + txt = self.prettyTxt(attacker, defender, texts) + self.shout("{}".format(txt)) + + blockchance = 0 + if defender.nextAction[0] == 'block': + if defender.nextAction[1] == attacker.nextAction[1]: + blockchance = self.config["moves"][defender.stance][defender.nextAction[0]][defender.nextAction[1]]["chance"] + blocktxts = self.config["moves"][defender.stance][defender.nextAction[0]][defender.nextAction[1]]["text"] + + + if (random.random() * 100) < blockchance * (blockidx / 100): + blocktxt = self.prettyTxt(attacker, defender, blocktxts) + self.shout("{}".format(blocktxt)) + else: + if defender.nextAction[0] == 'block': + self.shout("{} Tryed to block {} but failed miserably!".format(defender.nick, defender.nextAction[1])) + + + realdmg = (random.random() * dmg) + mindmg + + text = self.prettyTxt(attacker, defender, texts) + defender.hp -= realdmg + + if (random.random() * 100) < fallchance: # defender falls down? + defender.stance = 'ground' + falltxt = self.prettyTxt(attacker, defender, self.config['info']['stand2ground']) + self.shout("{}".format(falltxt)) + + + if defender.hp <= 0: + self.IRC.privmsg(self.IRC.channel, "\x02\x0305{} passed out.\x0f".format(defender.nick)) + self.state = "fight_over" + return + + if defender.hp < 25 and defender.first_time_lowhp: + defender.first_time_lowhp=False + lowhptxt = self.prettyTxt(attacker, defender, self.config['info']['lowhp']) + self.shout("{}".format(lowhptxt)) + + + if attacker.nextAction[0] == 'standup': # attacker gets up? + if (random.random() * 100) < standchance: # DO you get up? + attacker.stance = 'stand' + standtxt = self.prettyTxt(attacker, defender, self.config['info']['ground2stand']) + self.shout("{}".format(standtxt)) + + + + def prettyTxt(self, attacker, defender, txtlist): + txt = txtlist[random.randint(0, len(txtlist)-1)] + txt = txt.replace("%attacker%", "\x02\x03{}{}\x0f".format(attacker.colour, attacker.nick)) + txt = txt.replace("%defender%", "\x02\x03{}{}\x0f".format(defender.colour, defender.nick)) + return txt + + def shout(self, msg): + for f in self.fighters: + self.IRC.privmsg(f.nick, msg) + self.IRC.privmsg(self.IRC.channel, msg) diff --git a/fighter.py b/fighter.py new file mode 100644 index 0000000..003c168 --- /dev/null +++ b/fighter.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + + + + +class Fighter(object): + def __init__(self, nick, colour): + + self.nick = nick + self.colour = colour + + self.hp = 100 + self.stance = 'stand' + + self.nextAction = None + + self.advantage = False + self.groundpos = None + + self.first_time_lowhp = True + + self.wins = 0 + self.looses = 0 diff --git a/irc.py b/irc.py new file mode 100644 index 0000000..82c5e2b --- /dev/null +++ b/irc.py @@ -0,0 +1,202 @@ +#!/usr/bin/python3 + +import sys, socket, ssl, time, os, re + +from log import Colors, Log +from mircformat import MIRCFormat +from ircReload import recompile + +from ircCommands import IrcCommands + + +server = 'irc.servercentral.net' +port = 9999 +channel = ('#wololo', None) # (chan, key) +use_ssl = True + +nickname = 'devbruce' +username = 'rrarrar' +realname = '** WE BOTTIN **' + +optkey= "!" +timeout=0.4 + +DEBUG = True +sys.dont_write_bytecode = True + + + + +class Irc(object): + + def __init__(self): + self.sock = None + self.lag=False + + self.last_cmd={} + self.flood_flag={} + self.flood_count={} + + self.mirc = MIRCFormat() + + self.optkey = optkey + + self.log = Log(DEBUG) + + self.server = server + self.port = port + self.ssl = use_ssl + + self.nick = nickname + self.user = username + self.real = realname + + self.channel, self.chankey = channel + + self.nameslists = {} + self.nameslistFlag = {} + + self.cmds = IrcCommands(self) + + self.timeouts = {} + + def connect(self): + try: + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if use_ssl: + self.sock = ssl.wrap_socket(self.sock) + self.sock.connect((server, port)) + except Exception as e: + self.log.error("Connexion failed", e) + return + + + def run(self): + self.connect() + self.register() + self.listen() + + def register(self): + self.log.info("Identifying...") + self.raw("USER {} 0 * :{}".format(self.user, self.real)) + self.raw("NICK {}".format(self.nick)) + + def updateNick(self): + self.log.info("Updating NICK to {}".format(self.nick)) + self.raw("NICK {}".format(self.nick)) + + def listen(self): + while True: + if self.lag: + self.lag=False + data += self.sock.recv(1024).decode('utf-8', 'ignore') + else: + data = self.sock.recv(1024).decode('utf-8', 'ignore') + + for line in [x.split() for x in data.split("\r\n") if len(x.split()) > 1]: + self.log.info("<< {}".format(' '.join(line))) + + if line[0][1:] == 'ING': + self.raw("PONG {}".format(line[1])) + + elif line[1] == '001': # connected + self.join() + + elif line[1] == 'JOIN': # Someone joined a channel + self.log.info("{} JOIN to {}".format(line[0], line[2])) + pass + + elif line[1] == 'PART': # Someone emopart a channel + self.log.info("{} PART from {}".format(line[0], line[2])) + pass + + elif line[1] == '433': # Nick already in use + self.nick += "_" + self.updateNick() + + elif line[1] == 'KICK': #Got kicked lmao + if line[0][1:].split("@")[0].split("!") == self.nick: + self.log.warn("Got kicked from {} !".format(line[2])) + chan = line[2] + if chan == self.channel: + self.join() + + elif line[1] == 'INVITE': + self.log.info("{} invited the bot to {}".format(line[0][1:].split("!")[0], line[3][1:])) + self.join(line[3][1:]) + + + elif line[1] == 'PRIVMSG': + nick,user = line[0][1:].split("@")[0].split("!") + user = user[1:] if user[0] == '~' else user + host = line[0].split("@")[1] + self.handle_msg(line[2], self.isAdmin(line[0][1:]), nick, user, host, ' '.join(line[3:])[1:]) + + def join(self): + self.log.info("Now joining {} ...".format(self.channel)) + self.raw("JOIN {} {}".format(self.channel, self.chankey)) if self.chankey else self.raw("JOIN {}".format(self.channel)) + + + def raw(self, msg, timeout=None): + msg = msg.replace("\r", "") + msg = msg.replace("\n", "") + self.log.info(">> " + msg) + self.sock.send(bytes(msg + "\r\n", 'utf-8')) + if timeout: + time.sleep(timeout) + + def isAdmin(self, ident): + ret = False + for line in [line.strip() for line in open('admins', 'r').readlines() if line]: + if re.compile(line.replace('*', '.*')).search(ident): + ret = True + return ret + + + def handle_msg(self, chan, admin, nick, user, host, msg): + args = msg.split() + if admin: + if args[0] == '{}reload'.format(self.optkey): + ret = recompile(args[1]) # Let you add new code to the bot without restarting it + if ret == True: + self.privmsg(chan, "{} recompiled successfully!".format(args[1])) + return + else: + self.privmsg(chan, "Man we had a issue while recompiling {}".format(args[1])) + self.log.error(ret) + return + + self.cmds.handle_msg(chan, admin, nick, user, host, msg) + + + def privmsg(self, chan, msg): + if chan not in self.timeouts: + self.timeouts[chan] = {'last_cmd': time.time(), 'burst': 0, 'timeout': 0} + self.raw("PRIVMSG {} :{}".format(chan, msg), self.timeouts[chan]['timeout']) + self.editTimeouts() + + + + def editTimeouts(self): + if (time.time() - self.timeouts[chan]['last_cmd']) < 3: + self.timeouts[chan]['burst'] += 1 + else: + self.timeouts[chan]['burst'] = 0 + + if self.timeouts[chan]['burst'] > 3: + self.timeouts[chan]['timeout'] += 0.075 + else: + self.timeouts[chan]['timeout'] = 0 + + if self.timeouts[chan]['timeout'] > 0.4: + self.timeouts[chan]['timeout'] = 0.4 + + self.timeouts[chan]['last_cmd'] = time.time() + + + def action(self, chan, msg): + self.privmsg(chan, "\x01ACTION {}\x01".format(msg)) + + +if __name__=='__main__': + Irc().run() diff --git a/ircCommands.py b/ircCommands.py new file mode 100644 index 0000000..ccaf77b --- /dev/null +++ b/ircCommands.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +import time +from fight import Fight + +class IrcCommands(object): + def __init__(self, IRC): + self.IRC = IRC + self.fight = Fight(self.IRC) + + def handle_msg(self, chan, admin, nick, user, host, msg): + args = msg.split() + if args[0][0] == self.IRC.optkey: + self.handle_cmd(chan, admin, nick, user, host, args[0][1:], args[1:]) + + + def check_flood(self, chan, nick): + if chan not in self.IRC.flood_flag: + self.IRC.flood_flag[chan] = False + if chan not in self.IRC.last_cmd: + self.IRC.last_cmd[chan] = 0 + + if self.IRC.flood_flag[chan] and (time.time() - self.IRC.last_cmd[chan]) < 5: + return True + if (time.time() - self.IRC.last_cmd[chan]) < 2 and self.IRC.flood_count[chan] > 2: + self.IRC.privmsg(chan, "\00305,01{}\00315 Slow down m8".format(nick)) + self.IRC.flood_flag[chan]=True + self.IRC.last_cmd[chan] = time.time() + return True + if (time.time() - self.IRC.last_cmd[chan]) < 1: + self.IRC.flood_count[chan]+=1 + self.IRC.privmsg(chan, "\00305,01{}\00315 Slow down m8".format(nick)) + self.IRC.last_cmd[chan] = time.time() + return True + + return False + + + + def handle_cmd(self, chan, admin, nick, user, host, cmd, args): + if chan == self.IRC.nick: + chan = nick + + if self.check_flood(chan, nick): + return + + if admin: + if cmd == 'raw': + if args[0].lower() == 'nick': + self.IRC.nick = args[1] + self.IRC.updateNick() + elif args[0].lower() == 'join': + self.IRC.join(" ".join(args[1:])) + else: + self.IRC.raw(" ".join(args)) + + + + if self.fight.state in ('inactive', 'waiting_fighter'): + if cmd == 'fight': + self.fight.addFighter(nick) + if self.fight.state == 'fighters_ready': + self.fight.startFight() + + else: + if cmd == 'status': + self.fight.getStatus(nick) + + + if self.fight.state == 'waiting_fighters_action': + if cmd == 'action': + if chan != self.IRC.channel: + self.fight.set_next_action(nick, args) + else: + self.IRC.privmsg(self.IRC.channel, "Not here retard your opponent can see your next move!") + + + self.IRC.flood_flag[chan] = False + self.IRC.flood_count[chan] = 0 + self.IRC.last_cmd[chan] = time.time() diff --git a/ircReload.py b/ircReload.py new file mode 100644 index 0000000..b10a898 --- /dev/null +++ b/ircReload.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +from importlib import reload +import sys + +def recompile(modulename): + try: + modImport = __import__(modulename) + except: + return "Error @ __import__({})".format(modulename) + + pycfile = modImport.__file__ + + modPath = pycfile.replace(".pyc", ".py") + + try: + f = open(modPath, "rU") + code = f.read() + except Exception as e: + return "Error @ open({}, 'rU') : {}".format(modPath, e) + + f.close() + + try: + compile(code, modulename, "exec") + except Exception as e: + return "Error @ compile({}..., {}, 'exec') : {}".format(code[:10], modulename, e) + + try: + exec(code) + except Exception as e: + return "Error @ execfile({}) : {}".format(modPath, e) + + + + reload(sys.modules[modulename]) + return True + + +print(recompile("ircCommands")) diff --git a/log.py b/log.py new file mode 100644 index 0000000..5c9f506 --- /dev/null +++ b/log.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 + + +class Colors(object): + class Format(object): + RESET = "\033[0m" + BOLD = "\033[1m" + DIM = "\033[2m" + UNDERLINED = "\033[4m" + BLINK = "\033[5m" + REVERSE = "\033[7m" + HIDDEN = "\033[8m" + + class Foreground(object): + DEFAULT = "\033[39m" + BLACK = "\033[30m" + RED = "\033[31m" + GREEN = "\033[32m" + YELLOW = "\033[33m" + BLUE = "\033[34m" + MAGENTA = "\033[35m" + CYAN = "\033[36m" + LIGHTGREY = "\033[37m" + DARKGREY = "\033[90m" + LIGHTRED = "\033[91m" + LIGHTGREEN = "\033[92m" + LIGHTYELLOW = "\033[93m" + LIGHTBLUE = "\033[94m" + LIGHTMAGENTA = "\033[95m" + LIGHTCYAN = "\033[96m" + WHITE = "\033[97m" + class Background(object): + DEFAULT = "\033[49m" + BLACK = "\033[40m" + RED = "\033[41m" + GREEN = "\033[42m" + YELLOW = "\033[43m" + BLUE = "\033[44m" + MAGENTA = "\033[45m" + CYAN = "\033[46m" + LIGHTGREY = "\033[47m" + DARKGREY = "\033[100m" + LIGHTRED = "\033[101m" + LIGHTGREEN = "\033[102m" + LIGHTYELLOW = "\033[103m" + LIGHTBLUE = "\033[104m" + LIGHTMAGENTA = "\033[105m" + LIGHTCYAN = "\033[106m" + WHITE = "\033[107m" + + def __init__(self): + self.format = self.Format() + self.fg = self.Foreground() + self.bg = self.Background() + +class Log(object): + def __init__(self, debug, func=print): + self.colors = Colors() + self.debug = debug + self.func = func + + def construct(self, *args): + return "".join(a for a in args) + + def info(self, msg): + if not self.debug: + self.func( self.construct( "[", self.colors.fg.LIGHTGREEN, "*", self.colors.fg.DEFAULT, "] ", msg ) ) + + def warn(self, msg): + if not self.debug: + self.func( self.construct( "[", self.colors.fg.LIGHTYELLOW, "!", self.colors.fg.DEFAULT, "] ", msg ) ) + + def error(self, msg, exception=None): + if not self.debug: + self.func( self.construct( "[", self.colors.fg.LIGHTRED, "x", self.colors.fg.DEFAULT, "] ", msg ) ) + if exception: + self.func( self.construct( "[", self.colors.fg.LIGHTRED, "x", self.colors.fg.DEFAULT, "] ", str(exception) ) ) diff --git a/mircformat.py b/mircformat.py new file mode 100644 index 0000000..0d81d70 --- /dev/null +++ b/mircformat.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +class MIRCFormat(object): + BOLD = "\x02" + ITALIC = "\x1D" + UNDERLINED = "\x1F" + REVERSE = "\x16" + RESET = "\x0F" + WHITE = "\x0300" + BLACK = "\x0301" + BLUE = "\x0302" + GREEN = "\x0303" + RED = "\x0304" + BROWN = "\x0305" + PURPLE = "\x0306" + ORANGE = "\x0307" + YELLOW = "\x0308" + LIGHTGREEN = "\x0309" + CYAN = "\x0310" + LIGHTCYAN = "\x0311" + LIGHTBLUE = "\x0312" + PINK = "\x0313" + GREY = "\x0314" + LIGHTGREY = "\x0315"