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 return
elif attacker.nextAction[0] == 'block': elif attacker.nextAction[0] == 'block':
tmp = attacker attacker, defender = defender, attacker
attacker = defender
defender = tmp
attacker.advantage = True attacker.advantage = True
defender.advantage = False 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. 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 :) 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 #!/usr/bin/python3
import sys, socket, ssl, time, os, re import sys, socket, ssl, time, os, re, select
sys.dont_write_bytecode = True sys.dont_write_bytecode = True
os.chdir(sys.path[0] or ".") os.chdir(sys.path[0] or ".")
@ -14,25 +14,11 @@ from ircReload import recompile
from ircCommands import IrcCommands 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): 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.sock = None
self.lag = False self.ep = None
self.last_cmd = {} self.last_cmd = {}
self.flood_flag = {} self.flood_flag = {}
@ -45,7 +31,7 @@ class IrcBot(object):
self.server = server self.server = server
self.port = port self.port = port
self.ssl = use_ssl self._ssl = use_ssl
self.nick = nickname self.nick = nickname
self.user = username self.user = username
@ -55,75 +41,142 @@ class IrcBot(object):
self.channel,self.chankey = channel self.channel,self.chankey = channel
self.recvQueue = self.sendQueue = []
self.partialLine = ''
def connect(self): def connect(self):
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if use_ssl: self.sock.setblocking(0)
self.sock = ssl.wrap_socket(self.sock) try:
self.sock.connect((server, port)) self.sock.connect((self.server, self.port))
except Exception as e: except BlockingIOError:
self.log.error("Connexion failed", e) pass
return 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): def run(self):
self.connect() while True:
self.register() events = self.ep.poll(1)
self.listen() 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): def register(self):
self.raw("USER {} 0 * :{}".format(self.user, self.real)) self.queue("USER {} 0 * :{}".format(self.user, self.real))
self.raw("NICK {}".format(self.nick)) self.queue("NICK {}".format(self.nick))
def updateNick(self): 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: while True:
try: try:
if self.lag: newLines = self.sock.recv(512)
self.lag=False except BlockingIOError:
data += self.sock.recv(1024).decode('utf-8', 'ignore') self.recvQueue = lines
return
except ssl.SSLWantReadError:
self.recvQueue = lines
return
if not newLines:
lines += [None]
break
elif len(newLines) == 0:
break
else: else:
data = self.sock.recv(1024).decode('utf-8', 'ignore') 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
for line in [x.split() for x in data.split("\r\n") if len(x.split()) > 1]: self.recvQueue = lines
# self.log.info("<< {}".format(' '.join(line))) 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': if line[0][1:] == 'ING':
ircEvents.eventPING(self, line) ircEvents.eventPING(self, line)
else: else:
try: try:
if hasattr(ircEvents, "event{}".format(line[1].upper())): if hasattr(ircEvents, "event{}".format(line[1].upper())):
getattr(ircEvents, "event{}".format(line[1].upper()))(self, line) getattr(ircEvents, "event{}".format(line[1].upper()))(self, line)
except Exception as e: except Exception as e:
self.log.error("Error in getattr()", e) self.log.error("Error in getattr()", e)
pass
except (UnicodeDecodeError, UnicodeEncodeError): del self.recvQueue[0]
pass
except KeyboardInterrupt:
self.log.warn("^C, Exiting...")
return
except Exception as e:
self.log.error("Exception in listen()", e)
pass
def join(self): 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("\r", "")
msg = msg.replace("\n", "") msg = msg.replace("\n", "")
self.log.info(">> " + msg) if len(msg) > (512 - len("\r\n")):
self.sock.send(bytes(msg + "\r\n", 'utf-8')) for i in range(0, len(msg), 512 - len("\r\n")):
if timeout: m = msg[i:512 - len("\r\n")]
time.sleep(timeout) m = m + "\r\n"
self.sendQueue += [m]
else:
msg = msg + "\r\n"
self.sendQueue += [msg]
def isAdmin(self, ident): def isAdmin(self, ident):
ret = False ret = False
@ -134,6 +187,8 @@ class IrcBot(object):
def handle_msg(self, chan, admin, nick, user, host, msg): def handle_msg(self, chan, admin, nick, user, host, msg):
if len(msg) == 0:
return
args = msg.split() args = msg.split()
if admin: if admin:
if args[0] == '{}reload'.format(self.optkey): if args[0] == '{}reload'.format(self.optkey):
@ -152,7 +207,8 @@ class IrcBot(object):
def privmsg(self, chan, msg): def privmsg(self, chan, msg):
if chan not in self.timeouts: if chan not in self.timeouts:
self.timeouts[chan] = {'last_cmd': time.time(), 'burst': 0, 'timeout': 0} 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) self.editTimeouts(chan)

View File

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

View File

@ -3,7 +3,7 @@
import time import time
def eventPING(IRC, line): def eventPING(IRC, line):
IRC.raw("PONG {}".format(line[1])) IRC.queue("PONG {}".format(line[1]))
def event001(IRC, line): def event001(IRC, line):
IRC.join() IRC.join()
@ -29,7 +29,7 @@ def eventQUIT(IRC, line):
if line[0][1:].split("@")[0].split("!")[0] == IRC.nick: if line[0][1:].split("@")[0].split("!")[0] == IRC.nick:
IRC.log.warn("quit ! Reconnecting in 15 seconds..") IRC.log.warn("quit ! Reconnecting in 15 seconds..")
time.sleep(15) time.sleep(15)
IRC.run() IRC.init()
def eventINVITE(IRC, line): def eventINVITE(IRC, line):
IRC.log.info("{} invited the bot to {}".format(line[0][1:].split("!")[0], line[3][1:])) 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("!") nick,user = line[0][1:].split("@")[0].split("!")
user = user[1:] if user[0] == '~' else user user = user[1:] if user[0] == '~' else user
host = line[0].split("@")[1] host = line[0].split("@")[1]
try:
IRC.handle_msg(line[2], IRC.isAdmin(line[0][1:]), nick, user, host, ' '.join(line[3:])[1:]) 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 ".") os.chdir(sys.path[0] or ".")
sys.path += ("irc", "IRCUFC") 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__': if __name__ == '__main__':
import irc import irc
irc.IrcBot().run() irc.IrcBot(nickname, username, realname, server, port, use_ssl, channel, optkey, DEBUG).init()