epoll(2) la ^_^

This commit is contained in:
wr34k 2018-07-05 01:47:01 +02:00
parent 005a6cfbed
commit 27db732576
7 changed files with 148 additions and 76 deletions

View File

@ -217,9 +217,7 @@ class Fight(object):
return
elif attacker.nextAction[0] == 'block':
tmp = attacker
attacker = defender
defender = tmp
attacker, defender = defender, attacker
attacker.advantage = True
defender.advantage = False

View File

@ -35,3 +35,6 @@ If both fighters are attacking at the same time, then the one who will hit is ra
Using 'block' with the right level (high, middle, low) will give you a great chance to block the next hit. If so, you won't loose HP, and you'll take the advantage for the next round.. Be careful though, if for instance you block high and your opponent attacks you low or middle, you'll have 100% chance of taking the hit (Except if the strike fails). Blocking chance depend on your stance.
There's a chance for fighters to fall down. In this case, hits will be much less powerful, and your opponent will do huge damage. If both fighters are on the ground, then one of them will be above the other. (The second fighter to fall will be above. Then, the one with the advantage will be above.) You'll have to use the '**!action standup**' command in order to .. stand up :)
**Shoutout to arab for the epoll(2) idea, and for [araboly](https://github.com/lalbornoz/araboly) which remains the best IRC game out there!**

View File

@ -1 +1 @@
{"wreek": {"wins": 2, "looses": 0}, "wr34k": {"wins": 0, "looses": 2}}
{"wreek": {"wins": 2, "looses": 2}, "wr34k": {"wins": 2, "looses": 2}}

View File

@ -1,6 +1,6 @@
#!/usr/bin/python3
import sys, socket, ssl, time, os, re
import sys, socket, ssl, time, os, re, select
sys.dont_write_bytecode = True
os.chdir(sys.path[0] or ".")
@ -14,25 +14,11 @@ from ircReload import recompile
from ircCommands import IrcCommands
server = 'irc.underworld.no'
port = 9999
channel = ('#IRCUFC', None) # (chan, key)
use_ssl = True
nickname = 'IRCUFC'
username = 'McBuffer'
realname = '** WE FIGHTIN **'
optkey= "!"
DEBUG = True
class IrcBot(object):
def __init__(self):
def __init__(self, nickname="IRCUFC", username="McBuffer", realname="WE FIGHTIN", server="irc.underworld.no", port=9999, use_ssl=True, channel=("#IRCUFC", None), optkey="!", DEBUG=True):
self.sock = None
self.lag = False
self.ep = None
self.last_cmd = {}
self.flood_flag = {}
@ -45,7 +31,7 @@ class IrcBot(object):
self.server = server
self.port = port
self.ssl = use_ssl
self._ssl = use_ssl
self.nick = nickname
self.user = username
@ -55,75 +41,142 @@ class IrcBot(object):
self.channel,self.chankey = channel
self.recvQueue = self.sendQueue = []
self.partialLine = ''
def connect(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setblocking(0)
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
self.sock.connect((self.server, self.port))
except BlockingIOError:
pass
socketfd = self.sock.fileno()
self.ep = select.epoll()
self.ep.register(self.sock.fileno(), select.EPOLLIN | select.EPOLLOUT)
ready = False
while not ready:
events = self.ep.poll(1)
for _,evt in events:
if evt & select.EPOLLOUT:
ready = True
break
if self._ssl:
self.sock = ssl.wrap_socket(self.sock, do_handshake_on_connect=False)
ready = False
while not ready:
events = self.ep.poll(1)
for _,evt in events:
if evt & select.EPOLLOUT:
try:
self.sock.do_handshake()
ready = True
except ssl.SSLWantReadError:
pass
def init(self):
self.connect()
self.register()
self.run()
def run(self):
self.connect()
self.register()
self.listen()
while True:
events = self.ep.poll(1)
for _,evt in events:
if evt & select.EPOLLIN:
self._recv()
elif evt & select.EPOLLOUT and len(self.sendQueue) > 0:
self._send()
self.handle_events()
def register(self):
self.raw("USER {} 0 * :{}".format(self.user, self.real))
self.raw("NICK {}".format(self.nick))
self.queue("USER {} 0 * :{}".format(self.user, self.real))
self.queue("NICK {}".format(self.nick))
def updateNick(self):
self.raw("NICK {}".format(self.nick))
self.queue("NICK {}".format(self.nick))
def listen(self):
def _send(self):
while self.sendQueue:
for m in self.sendQueue:
self.log.info(">> {}".format(m.replace("\r\n", "")))
msg = self.sendQueue[0]
datasent = self.sock.send(msg.encode())
if datasent < len(msg):
self.sendQueue[0] = msg[datasent:]
return False
else:
del self.sendQueue[0]
return True
def _recv(self):
lines = []
while True:
try:
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':
ircEvents.eventPING(self, line)
else:
try:
if hasattr(ircEvents, "event{}".format(line[1].upper())):
getattr(ircEvents, "event{}".format(line[1].upper()))(self, line)
except Exception as e:
self.log.error("Error in getattr()", e)
pass
except (UnicodeDecodeError, UnicodeEncodeError):
pass
except KeyboardInterrupt:
self.log.warn("^C, Exiting...")
newLines = self.sock.recv(512)
except BlockingIOError:
self.recvQueue = lines
return
except ssl.SSLWantReadError:
self.recvQueue = lines
return
if not newLines:
lines += [None]
break
elif len(newLines) == 0:
break
else:
newLines = str(newLines, 'utf-8', 'ignore')
if newLines[-2:] == "\r\n":
msgs = (self.partialLine + newLines).split("\r\n")[:-1]
self.partialLine = ""
else:
msgs = (self.partialLine + newLines).split("\r\n")
if len(msgs) > 1:
self.partialLine = msgs[-1]
msgs = msgs[:-1]
lines += msgs
except Exception as e:
self.log.error("Exception in listen()", e)
pass
self.recvQueue = lines
for m in self.recvQueue():
self.log.info("<< {}".format(m))
def handle_events(self):
while self.recvQueue:
data = self.recvQueue[0]
self.log.info("<< {}".format(data))
line = data.split(" ")
if line[0][1:] == 'ING':
ircEvents.eventPING(self, line)
else:
try:
if hasattr(ircEvents, "event{}".format(line[1].upper())):
getattr(ircEvents, "event{}".format(line[1].upper()))(self, line)
except Exception as e:
self.log.error("Error in getattr()", e)
del self.recvQueue[0]
def join(self):
self.raw("JOIN {} {}".format(self.channel, self.chankey)) if self.chankey else self.raw("JOIN {}".format(self.channel))
self.queue("JOIN {} {}".format(self.channel, self.chankey)) if self.chankey else self.queue("JOIN {}".format(self.channel))
def raw(self, msg, timeout=None):
def queue(self, msg):
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)
if len(msg) > (512 - len("\r\n")):
for i in range(0, len(msg), 512 - len("\r\n")):
m = msg[i:512 - len("\r\n")]
m = m + "\r\n"
self.sendQueue += [m]
else:
msg = msg + "\r\n"
self.sendQueue += [msg]
def isAdmin(self, ident):
ret = False
@ -134,6 +187,8 @@ class IrcBot(object):
def handle_msg(self, chan, admin, nick, user, host, msg):
if len(msg) == 0:
return
args = msg.split()
if admin:
if args[0] == '{}reload'.format(self.optkey):
@ -152,7 +207,8 @@ class IrcBot(object):
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.queue("PRIVMSG {} :{}".format(chan, msg))
time.sleep(self.timeouts[chan]['timeout'])
self.editTimeouts(chan)

View File

@ -52,7 +52,7 @@ class IrcCommands(object):
elif args[0].lower() == 'join':
self.IRC.join(" ".join(args[1:]))
else:
self.IRC.raw(" ".join(args))
self.IRC.queue(" ".join(args))
if cmd == 'cancel' and self.fight.state != 'inactive':
self.IRC.privmsg(chan, "Fight cancelled.")

View File

@ -3,7 +3,7 @@
import time
def eventPING(IRC, line):
IRC.raw("PONG {}".format(line[1]))
IRC.queue("PONG {}".format(line[1]))
def event001(IRC, line):
IRC.join()
@ -29,7 +29,7 @@ def eventQUIT(IRC, line):
if line[0][1:].split("@")[0].split("!")[0] == IRC.nick:
IRC.log.warn("quit ! Reconnecting in 15 seconds..")
time.sleep(15)
IRC.run()
IRC.init()
def eventINVITE(IRC, line):
IRC.log.info("{} invited the bot to {}".format(line[0][1:].split("!")[0], line[3][1:]))
@ -38,4 +38,7 @@ def eventPRIVMSG(IRC, line):
nick,user = line[0][1:].split("@")[0].split("!")
user = user[1:] if user[0] == '~' else user
host = line[0].split("@")[1]
IRC.handle_msg(line[2], IRC.isAdmin(line[0][1:]), nick, user, host, ' '.join(line[3:])[1:])
try:
IRC.handle_msg(line[2], IRC.isAdmin(line[0][1:]), nick, user, host, ' '.join(line[3:])[1:])
except:
pass

14
main.py
View File

@ -5,7 +5,19 @@ sys.dont_write_bytecode = True
os.chdir(sys.path[0] or ".")
sys.path += ("irc", "IRCUFC")
server = 'irc.arabs.ps'
port = 6697
channel = ('#IRCUFC', None) # (chan, key)
use_ssl = True
nickname = 'IRCUFC'
username = 'McBuffer'
realname = '** WE FIGHTIN **'
optkey= "!"
DEBUG = True
if __name__ == '__main__':
import irc
irc.IrcBot().run()
irc.IrcBot(nickname, username, realname, server, port, use_ssl, channel, optkey, DEBUG).init()