import Blender import textwrap import sys import string import threading import socket #import Blender #import timer class IRC: def __init__(self): self.text = "" self.socket = socket.socket() self.interval = threading.Timer(0.1, self.getData) self.buffer = "" self.channel = "" def set_output(self, output): self.output = output def connect(self, host, port, nick, real): self.nick = nick self.socket.connect((host, port)) self.socket.send("NICK %s\r\n" % nick) self.socket.send("USER %s %s bircsrv :%s\r\n" % ("BlenderIRC", host, real)) readbuffer = "" while 1: readbuffer=readbuffer+self.socket.recv(1024) data=string.split(readbuffer, "\n") readbuffer=data.pop( ) Blender.Draw.Redraw() for line in data: line=string.rstrip(line) words=string.split(line) print line if words[0] == "NOTICE": #self.text.join("%s \r\n" % line) self.output.add_text(line) if words[1] == "004": #self.text.join("Connected...\r\n") self.output.add_text("Connected...") self.interval.start() return 1 if words[1] == "433": #self.text.join("Nick already in use...\r\n") self.output.add_text("Nick already in use...") return 0 return 1 def join(self, channel): self.channel = channel self.socket.send("JOIN %s\r\n" % channel) self.output.add_text("Joining....") def discon(self, channel): self.socket.send("PART %s\r\n" % channel) self.output.add_text("Disconnecting...") self.socket.close() self.output.add_text("***Disconnected***") def sendText(self, text): if text <> "p": self.socket.send("PRIVMSG %s :%s\r\n" % (self.channel, text)) def getData(self): self.buffer = self.buffer + self.socket.recv(1024) lines = self.buffer.split("\n") self.buffer = lines.pop() Blender.Draw.Redraw() for line in lines: line = line.rstrip() line = line.split(" ") print line if not line: return if line[1] == "PRIVMSG": nick = line[0].split("!")[0][1:] msg = string.join(line[3:])[1:] self.text.join("%s: %s\r\n" % (nick, msg)) #<----------------- self.output.add_text("<%s:> %s" % (nick, msg)) if msg.split()[0] == "!stop": if msg.split()[1] == self.nick: self.interval = None self.socket.send("PART %s\r\n" % self.channel) sys.exit() #raise RuntimeError else: self.output.add_text("%s is not a blenderIRC nick" % msg.split()[1]) elif msg == "!obj": pass #obj = Blender.Object.GetSelected()[0]: #self.socket.send("PRIVMSG %s :%s\r\n" % (self.channel, string.join([" elif msg.split()[0] == "!mock": self.sendText("%s smells like 4 month old tuna" % msg.split()[1]) else: self.text.join(nick.join("%s \r\n" % msg)) continue if line[0] =="PING": self.socket.send("%s\r\n" % line[1]) continue if line[1] == "353": self.names = line[5:] self.interval = threading.Timer(0.1, self.getData) self.interval.start() def start(self): self.interval.start() #while 1: # self.getData() # event() def nil(): pass #test = IRC() #if test.connect("irc.freenode.net", 6667, "_timbo3_", "TimW"): # test.join("#timmeh") # test.start(nil) #else: # raise RuntimeError class textbox: def __init__(self): self.text = "" self.buffer = "" self.obj = Blender.Draw.Create("") self.caption = Blender.Draw.Create("") def settext (self, val): self.text = self.text + val def gettext (self): return self.text text = property(gettext, settext) def setbuffer(self, val): self.buffer = self.buffer + val def getbuffer(self): return self.buffer buffer = property(getbuffer, setbuffer) def set_parent(self, par): self.parent = par def set_output(self, output): self.output = output def capture_keys(self, event_man): for x in range(Blender.Draw.ZKEY-Blender.Draw.AKEY): event_man.add_event(x + Blender.Draw.AKEY, self.handle_key_event, 1) event_man.add_event(Blender.Draw.RETKEY, self.handle_key_event, 1) event_man.add_event(Blender.Draw.BACKSPACEKEY, self.handle_key_event, 1) event_man.add_event(Blender.Draw.SPACEKEY, self.handle_key_event, 1) def parent_to(self, scroll): self.scroll = scroll def handle_key_event(self, key, val): if val == 0: if key == Blender.Draw.RETKEY: self.scroll.add_text("<%s> %s" % (self.output.nick,self.text)) self.output.sendText(self.text) self.text = "" elif key == Blender.Draw.BACKSPACEKEY: self.text = self.text[:len(self.text)-1] elif key == Blender.Draw.SPACEKEY: self.text = self.text+ " " else: if Blender.Window.GetKeyQualifiers() & Blender.Window.Qual.SHIFT: self.text = self.text + chr(key).capitalize() else: self.text = self.text + chr(key) def draw(self): Blender.BGL.glBegin(Blender.BGL.GL_LINE_LOOP) # begin a vertex-data list Blender.BGL.glVertex2i(24,12) Blender.BGL.glVertex2i(Blender.Window.GetAreaSize()[0] - 24,12) Blender.BGL.glVertex2i(Blender.Window.GetAreaSize()[0] - 24,32) Blender.BGL.glVertex2i(24,32) Blender.BGL.glEnd() Blender.BGL.glRasterPos2i(28, 16) self.obj = Blender.Draw.Text(self.text) Blender.BGL.glRasterPos2i(28, 38) self.caption = Blender.Draw.Text("Local:") class buttons: def __init__(self, event_man): self.connect_but = Blender.Draw.Create(0.0) self.join_but = Blender.Draw.Create(0.0) self.dis_but = Blender.Draw.Create(0.0) self.connect_evt = event_man.add_bevent(self.connect) self.join_evt = event_man.add_bevent(self.join) self.dis_evt = event_man.add_bevent(self.disconnect) def controllee(self, obj): self.controllee = obj def connect(self): self.nick = Blender.Draw.PupStrInput("Nick: ", "", 100) self.controllee.connect("irc.freenode.net", 6667, self.nick, "BIRC") #code to call connection function def join(self): self.channel = Blender.Draw.PupStrInput("Channel: ", "#blender", 100) self.controllee.join(self.channel) # code to call joining function def disconnect(self): self.controllee.discon(self.channel) #code to disconnect def draw(self): width = int((Blender.Window.GetAreaSize()[0] - 48)/3) height = 24 bottom = 56 left = 24 self.connect_but = Blender.Draw.Button("Connect", self.connect_evt, width*0 + left, bottom, width, height, "Connect to IRC server") self.join_but = Blender.Draw.Button("Join", self.join_evt, width*1 + left, bottom, width, height, "Join to IRC channel") self.dis_but = Blender.Draw.Button("Disconnect", self.dis_evt, width*2 + left, bottom, width, height, "Disconnect from IRC server") class scrolling_text: instances = {} text = [] def __init__(self, name): scrolling_text.instances[name] = self self.text = "" self.update = 0.1 self.caption_obj = Blender.Draw.Create("IRC Chat:") self.caption = "IRC Chat:" self.max_lines = 0 self.num_lines = 0 self.text_spacing = 16 self.current_line = 0 self.max_lines = 0 #self.event_man = event_manager def setcap(self, val): self.caption = val def getcap(self): return self.caption caption = property(getcap, setcap) def add_text(self, text): scrolling_text.text.append(text) def draw(self): self.max_lines = len(scrolling_text.text) self.top = Blender.Window.GetAreaSize()[1] - 24 self.right = Blender.Window.GetAreaSize()[0] - 24 self.bottom = 108 self.left = 24 self.space = 16 #main rect. Blender.BGL.glBegin(Blender.BGL.GL_LINE_LOOP) # begin a vertex-data list Blender.BGL.glVertex2i(self.left,self.bottom) Blender.BGL.glVertex2i(self.right,self.bottom) Blender.BGL.glVertex2i(self.right, self.top) Blender.BGL.glVertex2i(self.left,self.top) Blender.BGL.glEnd() #scrollbar Blender.BGL.glBegin(Blender.BGL.GL_LINE_LOOP) # begin a vertex-data list Blender.BGL.glVertex2i(self.right - self.space,self.bottom) Blender.BGL.glVertex2i(self.right,self.bottom) Blender.BGL.glVertex2i(self.right, self.top) Blender.BGL.glVertex2i(self.right - self.space,self.top) Blender.BGL.glEnd() #up button Blender.BGL.glBegin(Blender.BGL.GL_LINE_LOOP) # begin a vertex-data list Blender.BGL.glVertex2i(self.right - self.space,self.top - self.space) Blender.BGL.glVertex2i(self.right - int(self.space)/2,self.top) Blender.BGL.glVertex2i(self.right,self.top - self.space) Blender.BGL.glVertex2i(self.right - self.space,self.top - self.space) Blender.BGL.glEnd() #down button Blender.BGL.glBegin(Blender.BGL.GL_LINE_LOOP) # begin a vertex-data list Blender.BGL.glVertex2i(self.right - self.space, self.bottom + self.space) Blender.BGL.glVertex2i(self.right - int(self.space)/2, self.bottom) Blender.BGL.glVertex2i(self.right, self.bottom + self.space) Blender.BGL.glVertex2i(self.right - self.space, self.bottom + self.space) Blender.BGL.glVertex2i(self.right - self.space,self.top ) Blender.BGL.glEnd() #scroll button if self.num_lines <> 0: percentage = self.current_line / self.num_lines else: percentage = 0 range = (self.top - self.space) - (self.bottom + self.space) top = (self.top - self.space) - int(percentage * range) bottom = top - self.space * 2 Blender.BGL.glBegin(Blender.BGL.GL_LINE_LOOP) # begin a vertex-data list Blender.BGL.glVertex2i(self.right - self.space + 1, bottom + 1) Blender.BGL.glVertex2i(self.right - 1, bottom + 1) Blender.BGL.glVertex2i(self.right - 1, top-1) Blender.BGL.glVertex2i(self.right - self.space + 1, top-1) Blender.BGL.glEnd() #caption Blender.BGL.glRasterPos2i(self.left, self.top + 4) self.caption_obj = Blender.Draw.Text(self.caption) range = self.top - self.bottom width = self.right - self.left ''' self.view_lines = int(range / self.text_spacing) if self.max_lines < self.view_lines: self.view_range = scrolling_text.text[self.current_line:] if self.current_line + self.view_lines < self.max_lines: self.view_range = scrolling_text.text[self.current_line:self.current_line + self.view_lines] else: self.view_range = scrolling_text.text[self.current_line:] self.cnt = 1 for line in self.view_range: Blender.BGL.glRasterPos2i(self.left + 8, self.top - self.text_spacing * self.cnt) Blender.Draw.Text(line) self.cnt += 1''' self.view_range = int(range / self.text_spacing) - 1 if self.max_lines < self.view_range: self.view_lines = scrolling_text.text if self.max_lines > self.view_range: self.view_lines = scrolling_text.text[self.max_lines - self.view_range:] self.cnt = 0 for line in self.view_lines: Blender.BGL.glRasterPos2i(self.left + 8, self.bottom + (self.text_spacing * self.view_range) - (self.cnt * self.text_spacing)) Blender.Draw.Text(line) self.cnt += 1 class event_man: def __init__(self): self.current_event = 2000 self.event_list = {} self.qual_list = {} self.bevent_list = {} self.draw_list = [] def add_event(self, event, callback, forward_ref=0): self.event_list[event] = [callback, forward_ref] def del_event(self, event): if self.event_list.has_key(event): del self.event_list[event] else: raise KeyError def add_qual_event(self, event, qual, callback, forward_ref=0): self.qual_list[(event, qual)] = [callback, forward_ref] def add_bevent(self, callback, forward_ref=0): self.current_event += 1 self.bevent_list[self.current_event] = [callback, forward_ref] return self.current_event def add_draw(self, obj): self.draw_list.append(obj) def event(self, event, val): if Blender.Window.GetKeyQualifiers() & Blender.Window.Qual.CTRL: if self.qual_list.has_key((event, Blender.Window.Qual.CTRL)): if self.qual_list[(event, Blender.Window.Qual.CTRL)][1]: self.qual_list[(event, Blender.Window.Qual.CTRL)][0](event, val) else: self.qual_list[(event, Blender.Window.Qual.CTRL)][0]() Blender.Draw.Redraw() else: if self.event_list.has_key(event): if self.event_list[event][1]: self.event_list[event][0](event, val) else: self.event_list[event][0]() Blender.Draw.Redraw() def bevent(self, event): if self.bevent_list.has_key(event): if self.bevent_list[event][1]: self.bevent_list[event][0](event, val) else: self.bevent_list[event][0]() def draw(self): for obj in self.draw_list: obj.draw() def register(self): Blender.Draw.Register(self.draw, self.event, self.bevent) manager = event_man() textbox = textbox() chat = scrolling_text("chat") textbox.parent_to(chat) opts = buttons(manager) irc = IRC() irc.set_output(chat) textbox.set_output(irc) opts.controllee(irc) textbox.capture_keys(manager) manager.add_event(Blender.Draw.QKEY, Blender.Draw.Exit) manager.add_qual_event(Blender.Draw.LKEY, Blender.Window.Qual.CTRL, Blender.Draw.Exit) manager.add_draw(textbox) manager.add_draw(chat) manager.add_draw(opts) manager.register()