./0000755000175000017500000000000011214514710007673 5ustar jojojojo./infon-devel.py0000755000175000017500000004444611214510611012466 0ustar jojojojo#!/usr/bin/python # encoding:utf8 # Infon-Devel # Copyright (C) 2006 Joachim Breitner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software PREFIX = './' import pygtk pygtk.require('2.0') import gtk import gobject import gtksourceview2 import os import sys if not PREFIX in sys.path: sys.path.insert(0, PREFIX) import connview import infonconn class ConnDialog(gtk.Dialog): def __init__(self,window): gtk.Dialog.__init__(self, "Connect to Infon Server", window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, ( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK, ) ) self.e_hostname = gtk.Entry() self.e_port = gtk.Entry() self.e_username = gtk.Entry() self.e_password = gtk.Entry() self.vbox.add(gtk.Label("Server")) self.vbox.add(self.e_hostname) self.vbox.add(gtk.Label("Port")) self.vbox.add(self.e_port) self.vbox.add(gtk.Label("Username")) self.vbox.add(self.e_username) self.vbox.add(gtk.Label("Password")) self.vbox.add(self.e_password) self.vbox.show_all() hostname = property( lambda self: self.e_hostname.get_text(), lambda self,v: self.e_hostname.set_text(v)) port = property( lambda self: self.e_port.get_text(), lambda self,v: self.e_port.set_text(v)) username = property( lambda self: self.e_username.get_text(), lambda self,v: self.e_username.set_text(v)) password = property( lambda self: self.e_password.get_text(), lambda self,v: self.e_password.set_text(v)) def run(self): response = gtk.Dialog.run(self) self.hide() return response def run_name_only(self): self.e_hostname.set_sensitive(False) self.e_port.set_sensitive(False) self.e_password.set_sensitive(False) response = gtk.Dialog.run(self) self.hide() self.e_hostname.set_sensitive(True) self.e_port.set_sensitive(True) self.e_password.set_sensitive(True) return response class InfonDevel: def new(self,action): # Check for possible changes! self.bugbuf.begin_not_undoable_action() self.bugbuf.set_text("") self.filename = None self.bugbuf.end_not_undoable_action() self.bugbuf.set_modified(False) self.bugbuf.place_cursor(self.bugbuf.get_start_iter()) def open(self, action): chooser = gtk.FileChooserDialog('Open bug...', None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) response = chooser.run() if response == gtk.RESPONSE_OK: filename = chooser.get_filename() if filename: self.open_file(filename) chooser.destroy() def open_file(self,filename): if os.path.isabs(filename): path = filename else: path = os.path.abspath(filename) try: txt = open(path).read() except: return False self.bugbuf.begin_not_undoable_action() self.bugbuf.set_text(txt) self.bugbuf.end_not_undoable_action() self.filename = path self.bugbuf.set_modified(False) self.bugbuf.place_cursor(self.bugbuf.get_start_iter()) def save(self,action): if not self.filename: self.save_as(action) else: if os.path.isabs(self.filename): path = self.filename else: path = os.path.abspath(self.filename) start = self.bugbuf.get_start_iter() end = self.bugbuf.get_end_iter() open(path,"w").write(self.bugbuf.get_text(start,end)) self.bugbuf.set_modified(False) def save_as(self,action): chooser = gtk.FileChooserDialog('Save bug as...', None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) if self.filename: chooser.set_current_name(self.filename) response = chooser.run() if response == gtk.RESPONSE_OK: filename = chooser.get_filename() if filename: self.filename = filename self.save(action) chooser.destroy() def server_settings(self,action): self.conndialog.hostname = self.conn.hostname self.conndialog.port = self.conn.port self.conndialog.username = self.conn.username self.conndialog.password = self.conn.password if self.conndialog.run() == gtk.RESPONSE_OK: self.conn.hostname = self.conndialog.hostname self.conn.port = self.conndialog.port self.conn.username = self.conndialog.username self.conn.password = self.conndialog.password def change_name(self,action): self.conndialog.hostname = self.conn.hostname self.conndialog.port = self.conn.port self.conndialog.username = self.conn.username self.conndialog.password = self.conn.password if self.conndialog.run_name_only() == gtk.RESPONSE_OK: self.conn.username = self.conndialog.username def commit_code(self, action): start = self.bugbuf.get_start_iter() end = self.bugbuf.get_end_iter() self.conn.upload(self.bugbuf.get_text(start,end)) def connect(self, action): self.conn.open_connection() def disconnect(self, action): self.conn.close_connection() def info(self,action): dialog = gtk.AboutDialog() dialog.set_authors(["Joachim Breitner "]) dialog.set_license("GPL") dialog.set_name("Infon Devel") dialog.set_website("http://infon.dividuum.de/") dialog.set_website_label("http://infon.dividuum.de/") # dialog.set_version("0.0") dialog.run() dialog.destroy() def delete_event(self, widget, event, data=None): # Change FALSE to TRUE and the main window will not be destroyed # with a "delete_event". return False def setup_menu(self): actions = gtk.ActionGroup("menu") actions.add_actions([ ('FileMenu', None, '_File'), ('new', gtk.STOCK_NEW, '_New', None, 'New Bug', self.new), ('openbug', gtk.STOCK_OPEN, '_Open Bug...', None, 'Open a new bug', self.open), ('savebug', gtk.STOCK_SAVE, '_Save Bug', None, 'Save the current bug',self.save), ('savebugas', gtk.STOCK_SAVE_AS, 'S_ave Bug As...', None, 'Save the current bug',self.save_as), ('quit', gtk.STOCK_QUIT, '_Quit', None, 'Quit the program', self.destroy), ('GameMenu', None, '_Game'), ('ViewMenu', None, '_View'), ('ChooseServer', gtk.STOCK_NETWORK, 'Choose _Server', None, 'Choose an Infon Server', self.server_settings), ('ChangeName', gtk.STOCK_EDIT, 'Change _Name', None, 'Change your Player Name', self.change_name), ('ChangeColor', gtk.STOCK_SELECT_COLOR, 'Change C_olor', None, 'Change your Player’s Color', lambda a: None), ('CommitBug', gtk.STOCK_APPLY, 'Commit _Bug', None, 'Commit your code to the server', self.commit_code), ('RestartBug', gtk.STOCK_REFRESH, '_Restart Bug', None, 'Restart the your bug’s main loops', lambda a: self.conn.reload()), ('Connect', gtk.STOCK_CONNECT, '_Connect to Server', None, 'Connect to Server', self.connect), ('Disconnect', gtk.STOCK_DISCONNECT, '_Disconnect from Server', None, 'Disconnect from Server', self.disconnect), ('HelpMenu', None, '_Help'), ('info', gtk.STOCK_INFO, '_Info', None, 'Information about this program', self.info), ]) actions.add_toggle_actions([ ('ShowNumbers', None, 'Show _Line Numbers', None, 'Toggle visibility of line numbers in the left margin', lambda a, s: s.set_show_line_numbers(a.get_active())), ('ShowMarkers', None, 'Show _Markers', None, 'Toggle visibility of markers in the left margin', lambda a, s: s.set_show_line_marks(a.get_active())), ('AutoIndent', None, 'Enable _Auto Indent', None, 'Toggle automatic auto indentation of text', lambda a, s: s.set_auto_indent(a.get_active())), #('InsertSpaces', None, 'Insert _Spaces Instead of Tabs', None, 'Whether to insert space characters when inserting tabulations', # lambda a, s: s.set_insert_spaces_instead_of_tabs(a.get_active())), ],self.bugview) self.ui = gtk.UIManager() self.ui.add_ui_from_string(''' ''') action = actions.get_action('ShowNumbers') action.set_active(self.bugview.get_show_line_numbers()) action = actions.get_action('ShowMarkers') action.set_active(self.bugview.get_show_line_marks()) action = actions.get_action('AutoIndent') action.set_active(self.bugview.get_auto_indent()) #action = actions.get_action('InsertSpaces') #action.set_active(self.bugview.get_insert_spaces_instead_of_tabs()) #action = actions.get_action('TabsWidth%d' % self.bugview.get_tabs_width()) #if action: # action.set_active(True) self.ui.insert_action_group(actions,0) def setup_bugview(self): self.bugbuf = gtksourceview2.Buffer() lm = gtksourceview2.LanguageManager() lang = lm.guess_language(None, "text/x-lua") self.bugbuf.set_highlight_syntax(True) self.bugbuf.set_language(lang) def set_bt_markers(blubb): begin, end = self.bugbuf.get_bounds() self.bugbuf.remove_source_marks(begin, end) for creature, line in self.conn.bt: if line: self.bugbuf.create_source_mark(None, "bt", line) self.conn.connect("new_bt",set_bt_markers) self.bugview = gtksourceview2.View(self.bugbuf) self.bugview.props.show_line_numbers = True self.bugview.props.show_line_marks = True self.bugview.props.auto_indent = True #self.bugview.props.insert_spaces_instead_of_tabs = True icon = gtk.gdk.pixbuf_new_from_file(PREFIX + 'marker.png') self.bugview.set_mark_category_pixbuf("bt",icon) def setup_connview(self): self.connview = connview.ConnView() self.connview.append_system('Welcome to InfonDevel\n') def new_message(conn,type,msg): if type == infonconn.DIR_NONE: self.connview.append_system(msg) if type == infonconn.DIR_INCOMING: self.connview.append_incoming(msg) if type == infonconn.DIR_OUTGOING: self.connview.append_outgoing(msg) self.conn.connect("new_message",new_message) #self.connview.append_incoming('Incoming\n') #self.connview.append_outgoing('Outgoing\n') #self.connview.append_outgoing('Outgoing\n') #self.connview.append_outgoing('Outgoing\n') def setup_statusbar(self): self.status = gtk.Statusbar() def setup_conn(self): self.conn = infonconn.InfonConn() def setup_title(self): def set_title(): title = '' title += "Infon Devel" if self.bugbuf.get_modified(): title += " ⋆ " else: title += " – " if self.filename: title += self.filename else: title += "[unnamed]" if self.bugbuf.get_modified(): title += " ⋆ " else: title += " – " state = self.conn.props.state if state == infonconn.STATE_PRESETUP: title += "[no server specified]" elif state == infonconn.STATE_OFFLINE: title += "[offline]" elif state == infonconn.STATE_CONNECTING: title += "%s@%s:%s [connecting]" % (self.conn.username, self.conn.hostname, self.conn.port) elif state == infonconn.STATE_CONNECTED: title += "%s@%s:%s" % (self.conn.username, self.conn.hostname, self.conn.port) elif state == infonconn.STATE_DISCONNECTING: title += "%s@%s:%s [disconnecting]" % (self.conn.username, self.conn.hostname, self.conn.port) self.window.props.title = title self.bugbuf.connect("modified-changed", lambda b: set_title()) self.conn.connect("notify::state", lambda c,p: set_title()) set_title() def setup_toolbarstates(self): actions = self.ui.get_action_groups()[0] def statebased(): state = self.conn.props.state online = state == infonconn.STATE_CONNECTED actions.get_action('ChangeName').set_sensitive(online) actions.get_action('ChangeColor').set_sensitive(online) actions.get_action('CommitBug').set_sensitive(online) actions.get_action('RestartBug').set_sensitive(online) actions.get_action('Connect').set_sensitive(not online) actions.get_action('Disconnect').set_sensitive(online) actions.get_action('ChooseServer').set_sensitive( state == infonconn.STATE_OFFLINE or state == infonconn.STATE_PRESETUP ) self.conn.connect("notify::state", lambda c,p: statebased()) statebased() def __init__(self): self.filename = None self.setup_conn() self.setup_bugview() self.setup_connview() self.setup_menu() self.setup_statusbar() pane = gtk.VPaned() frame = gtk.ScrolledWindow() frame.add(self.bugview) frame.props.shadow_type = gtk.SHADOW_IN frame.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) pane.pack1(frame, True) frame = gtk.ScrolledWindow() frame.add(self.connview) frame.props.shadow_type = gtk.SHADOW_IN frame.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) pane.pack2(frame, False) pane.props.position = 300 vbox1 = gtk.VBox() vbox1.pack_start(self.ui.get_widget('/MenuBar'), expand=False) vbox1.pack_start(self.ui.get_widget('/ToolBar'), expand=False) vbox1.pack_start(pane) vbox1.pack_start(self.status, expand=False) self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_default_size(700,432) # Golden Ratio :-) self.window.props.border_width = 0 self.window.add_accel_group(self.ui.get_accel_group()) #self.window.set_icon(gtk.gdk.pixbuf_new_from_file('icon.png')) self.window.connect("delete_event", self.delete_event) self.window.connect("destroy", self.destroy) self.window.add(vbox1) self.conndialog = ConnDialog(self.window) self.setup_title() self.setup_toolbarstates() self.bugview.grab_focus() self.window.show_all() def main(self): gtk.main() def destroy(self, widget, data=None): gtk.main_quit() if __name__ == "__main__": InfonDevel().main() # vim:ts=4:sw=4:sts=4:et ./marker.png0000644000175000017500000000073110532623633011672 0ustar jojojojoPNG  IHDR&N:bKGD pHYs  ~tIME  +xJyfIDAT(ROKp~:KB9" 1)VDAtԮ~>`>@ FCKɡ?5]ui4Dsx> L6vE\j2Gbǚ5E5~CY3.,|><"fi$q|0,z2»wxn{a(I@aԪ(O_;"ul|@b3(|  ^hC%xz`"o{>!o.Gnv,)z0l4-Blc(a]xQt=*iP%u$f=o$gMk}(Bz@N!H8uqG_o0\۾#7]0pP&IENDB`./connview.py0000644000175000017500000000300710532623633012104 0ustar jojojojo import gtk import pango class ConnView(gtk.TextView): def __init__(self,*args): gtk.TextView.__init__(self,*args) font_desc = pango.FontDescription('monospace 10') if font_desc: self.modify_font(font_desc) self.props.editable = False self.props.cursor_visible = False self.props.buffer.create_tag("system", foreground="#555") self.props.buffer.create_tag("incoming", foreground="blue") self.props.buffer.create_tag("outgoing", foreground="red") self.connect_after("realize",ConnView.realized) def realized(self): end = self.props.buffer.get_end_iter() self.scroll_to_iter(end,0.1) def append_system(self, text): buffer = self.props.buffer end = buffer.get_end_iter() buffer.insert_with_tags_by_name(end, text, "system") if self.flags() & gtk.REALIZED: self.scroll_mark_onscreen(buffer.get_insert()) def append_incoming(self, text): buffer = self.props.buffer end = buffer.get_end_iter() buffer.insert_with_tags_by_name(end, text, "incoming") if self.flags() & gtk.REALIZED: self.scroll_mark_onscreen(buffer.get_insert()) def append_outgoing(self, text): buffer = self.props.buffer end = buffer.get_end_iter() buffer.insert_with_tags_by_name(end, text, "outgoing") if self.flags() & gtk.REALIZED: self.scroll_mark_onscreen(buffer.get_insert()) # vim:ts=4:sw=4:sts=4:et ./infon-devel.10000644000175000017500000000125210534767644012207 0ustar jojojojo.TH INFON-DEVEL "1" "November 2006" "infon-devel" "User Commands" .SH NAME infon-devel \- write bots for the game infon .SH DESCRIPTION Infon is a game which simulates the live of simple bugs who eat, propagate, eat each other and evolve. The players can not control the bugs directly but write their "intelligence" in the simple script language lua and upload it to the game using a plain telnet connection. The code can then be modified even while the game is running. Infon Devel is a graphical lua editor with integration into the infon server and allows easy uploading of the code. It also marks the currently executed line of code. .SH SEE ALSO .BR infon (6) .BR infond (6) ./infonconn.py0000644000175000017500000002175310543006372012250 0ustar jojojojoimport gobject import random import os import pwd import asyncore import socket import errno import re STATE_PRESETUP = 0 # Nothing configured. Maybe not used. STATE_OFFLINE = 1 STATE_CONNECTING = 2 STATE_CONNECTED = 3 STATE_DISCONNECTING = 4 DIR_NONE = 0 DIR_INCOMING = 1 DIR_OUTGOING = 2 class InfonConn(gobject.GObject): __gproperties__ = { 'state' : ( gobject.TYPE_INT, 'state of the connection', '', STATE_PRESETUP, STATE_DISCONNECTING, STATE_OFFLINE, gobject.PARAM_READWRITE ), } __gsignals__ = { 'new_message' : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_STRING,) ), 'new_bt' : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (), ), } def __init__(self): gobject.GObject.__init__(self) self.state = STATE_OFFLINE #self.hostname = "infon.dividuum.de" self.hostname = "localhost" self.port = "1234" self._username = pwd.getpwuid(os.getuid())[0] self.password = "pw%04d" % random.randrange(0,10000) self.playerid = None self.socket = None self.outbuffer = "" self.codebuffer = "" self.btbuffer = "" self.waiting_code = None def do_get_property(self, property): if property.name == 'state': return self.state else: raise AttributeError, 'unknown property %s' % property.name def do_set_property(self, property, value): if property.name == 'state': self.state = value else: raise AttributeError, 'unknown property %s' % property.name def open_connection(self): assert not self.socket self.props.state = STATE_CONNECTING self.emit("new_message", DIR_NONE, "Connecting to %s:%s..." % (self.hostname,self.port)) self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setblocking(False) try: self.socket.connect( (self.hostname, int(self.port)) ) except socket.error, (x,s): if x != errno.EINPROGRESS: self.emit("new_message", DIR_NONE, "failed: %s!" % s) self.props.state = STATE_OFFLINE gobject.io_add_watch(self.socket, gobject.IO_OUT, self.connected) def start_writing(self): def outgoing(socket, condition): if len(self.codebuffer) > 0: sent = socket.send(self.codebuffer) self.emit("new_message", DIR_OUTGOING, "[your code...]\n") self.codebuffer = self.codebuffer[sent:] elif len(self.outbuffer) > 0: sent = socket.send(self.outbuffer) self.emit("new_message", DIR_OUTGOING, self.outbuffer[:sent]) self.outbuffer = self.outbuffer[sent:] return len(self.codebuffer) > 0 or len(self.outbuffer) > 0 gobject.io_add_watch(self.socket, gobject.IO_OUT, outgoing) def connected(self,s,condition): self.emit("new_message", DIR_NONE, "Connected!") gobject.io_add_watch(s, gobject.IO_IN | gobject.IO_PRI, self.incoming) player_re = re.compile("joined. player (\d+) ") def incoming(self, s, condition): data = "" try: data = s.recv(8192) except socket.error, (x,s): self.emit("new_message", DIR_NONE, "\nConnection Closed: %s!\n" % s) self.props.state = STATE_OFFLINE return False if data: self.emit("new_message", DIR_INCOMING, data) if self.state == STATE_CONNECTING: if data.find("Press ") != -1: self.send("\n") elif data.find("enter '?' for help") != -1: self.send("j\n") elif data.find("press enter for new player") != -1: self.send("\n") elif data.find("password for new player") != -1: self.send("%s\n" % self.password) elif data.find("joined. player") != -1: m = self.player_re.search(data) assert m self.playerid = int(m.group(1)) self.start_bting() assert data.find("> ") != -1 self.send ("n\n") if self.state == STATE_CONNECTING or self.state == STATE_CONNECTED: if data.find("Player Name:") != -1: self.send("%s\n" % self.username) self.props.state = STATE_CONNECTED if self.state == STATE_CONNECTED: if data.find("enter your lua code") != -1: assert self.waiting_code self.codebuffer = self.waiting_code self.waiting_code = None self.start_writing() elif data.find("traceback:") != -1: self.parse_backtrace(data) if data.find("> ") != -1: self.start_writing() return True def upload(self, code): assert self.props.state == STATE_CONNECTED self.waiting_code = "%s\n.\n" % code self.send("b\n") def reload(self): assert self.props.state == STATE_CONNECTED self.send("r\n") def send(self, txt): self.outbuffer += txt self.start_writing() def set_username(self,username): changed = self._username != username self._username = username if changed and self.props.state == STATE_CONNECTED: self.send("n\n") def close_connection(self): assert self.props.state == STATE_CONNECTED self.send("q\n") self.props.state = STATE_DISCONNECTING ### BT Getting ### def start_bting(self): #self.emit("new_message", DIR_NONE,"Connecting to %s:%s..." % (self.hostname,self.port)) self.btsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.btsocket.setblocking(False) try: self.btsocket.connect( (self.hostname, int(self.port)) ) except socket.error, (x,s): if x != errno.EINPROGRESS: self.emit("new_message", DIR_NONE, "BT socket failed: %s!" % s) gobject.io_add_watch(self.btsocket, gobject.IO_OUT, self.btconnected) def btconnected(self,s,condition): #self.emit("new_message", DIR_NONE, "Connected Backtrace-Getter") gobject.io_add_watch(s, gobject.IO_IN | gobject.IO_PRI, self.btincoming) def btincoming(self, s, condition): try: data = s.recv(8192) except socket.error, (x,s): self.btconnected = False return False if data: if data.find("Press ") != -1: self.btsend("\n") elif data.find("enter '?' for help") != -1: self.btsend("j\n") elif data.find("press enter for new player") != -1: self.btsend("%d\n" % self.playerid) elif data.find("password for player") != -1: self.btsend("%s\n" % self.password) elif data.find("joined. player ") != -1: gobject.timeout_add(200, self.get_backtrace); self.btconnected = True elif data.find("traceback:") != -1: self.parse_backtrace(data) return True creature_re = re.compile("^ 0: sent = socket.send(self.btbuffer) self.btbuffer = self.btbuffer[sent:] return len(self.btbuffer) gobject.io_add_watch(self.btsocket, gobject.IO_OUT, btoutgoing) ## Properties username = property( lambda s: s._username, set_username) gobject.type_register(InfonConn) # vim:ts=4:sw=4:sts=4:et