ChatdServerClientExample: Difference between revisions

From Arianne
Jump to navigation Jump to search
No edit summary
 
No edit summary
(No difference)

Revision as of 12:38, 30 January 2005

A very simple example for you, the lazy reader, who can't be bothered to read the manual! But note, this example is by no way a substitute of HowToWriteGamesUsingArianne and it is only intended for readers that want a light introduction to Arianne.

!Server First we create the server class using python. <verbatim> import marauroa.game.python.PythonRP

class ChatServer(marauroa.game.python.PythonRP):

 def __init__(self, zone):
   self._zone=zone
   self._removeAttributes=[]
 def execute(self, id, action):
   result=0
   player=self._zone.get(id)
   action_code=action.get("type")
   if action_code='chat':
     player.put('text',action.get('text'))
     self._zone.modify(player)
     self._removeAttributes.append(player)
     result=1
   return result
 def nextTurn(self):
   for player in self._removeAttributes:
     if player.has('text'):
       player.remove('text')
       self._zone.modify(player)
 def onInit(self, object):
   self._zone.add(object)
   return 1
 def onExit(self, objectid):
   self._zone.remove(objectid)
   return 1
 def onTimeout(self, objectid):
   return onExit(self,objectid)

</verbatim>

Ok, most of it is just trivial stuff. The core code is at execute and nextTurn. The execute method is the one called to execute the actions the client sends and it is really simple, it adds the messages content as a player attribute, and the trick thing is that is add the player a list so that it can be deleted the attribute in the next turn.

The nextTurn just delete the attributes that now are useless.

!Client The client is a bit more complex. We need to make it login and choose a character. We will use a curses wrapper for python. _TODO:_ Improve it <verbatim> import pyarianne import curses import os import time import signal import sys

def sendMessage(lines):

   text = ""
   for i in lines:
     text = text + i + "\n"
   action=pyarianne.RPAction()
   action.put("type","chat")
   action.put("content",text)
   pyarianne.send(action)


def paintStatusArea(text):

   statusArea.clear()
   statusArea.border()
   statusArea.addstr(1,1,text)
   statusArea.refresh()

def paintTextArea(history_lines):

   textArea.clear()
   textArea.border()
   textArea.addstr(0,3," The first marauroa-python-curses-chat client ")
   row=1
   for line_entry in history_lines:
     name = line_entry['name']
     text = line_entry['text']
     name = name.rjust(16)+": "
     textArea.addstr(row,1,name,curses.color_pair(1))
     textArea.addstr(text,curses.color_pair(2))
     row=row+1
   textArea.refresh()

def paintInputArea(text):

   inputArea.clear()
   inputArea.border()
   inputArea.addstr(1,1,">"+text)
   inputArea.refresh()

def repaintInputArea():

   global text
   paintInputArea(text)

def dostuffonCallback():

   if False:
      winmain.addstr(0,0,"Calling from Python!")

def printChatMessage(world):

   global history_lines
   if True:
      for i in world.objects:
        if world.objects[i].get("type") == "character":
           name = world.objects[i].get("name")
           if world.objects[i].has("?text"):
              text = world.objects[i].get("?text")
              text_lines = text.split("\n")
              for line in text_lines:
                  if line != "":
                     history_lines.append({'name': name,'text': line})
              #if overflow - remove first element
              while len(history_lines) > 18:
                 history_lines.pop(0)
              paintTextArea(history_lines)
              repaintInputArea()


def initCurses():

   stdscr = curses.initscr()
   curses.noecho()
   curses.cbreak()
   stdscr.keypad(True)
   stdscr.nodelay(True)
   if curses.has_colors():
      curses.start_color()
      curses.init_pair(1, curses.COLOR_BLUE,   curses.COLOR_BLACK);
      curses.init_pair(2, curses.COLOR_GREEN,  curses.COLOR_BLACK);
      curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK);
      curses.init_pair(4, curses.COLOR_RED,    curses.COLOR_BLACK);
      curses.init_pair(5, curses.COLOR_CYAN,   curses.COLOR_BLACK);
      curses.init_pair(6, curses.COLOR_MAGENTA,curses.COLOR_BLACK);
      curses.init_pair(7, curses.COLOR_WHITE,  curses.COLOR_BLACK);
   return stdscr

def uninitCurses(sign,arg2):

   signal.signal(sign, signal.SIG_IGN)
   try:
     curses.nocbreak()
     stdscr.keypad(0)
     stdscr.nodelay(0)
     curses.echo()
     curses.endwin()
     print "Exiting by signal "+ str(sign)
   except err:
     print "Exception: " +str(err)
   sys.exit(0)

stdscr = initCurses()

  1. register singal handler to be able to restore the console

signal.signal(signal.SIGINT, uninitCurses) signal.signal(signal.SIGTERM, uninitCurses)

begin_x = 0 ; begin_y = 0 height = 20 ; width = 100 textArea = curses.newwin(height, width, begin_y, begin_x)

begin_x = 0 ; begin_y = 20 height = 3 ; width = 100 inputArea = curses.newwin(height, width, begin_y, begin_x) inputArea.keypad(True) inputArea.nodelay(True)

begin_x = 0 ; begin_y = 23 height = 3 ; width = 100 statusArea = curses.newwin(height, width, begin_y, begin_x)

world=pyarianne.World() perceptionHandler=pyarianne.PerceptionHandler() pyarianne.setIdleMethod(dostuffonCallback) pyarianne.connectToArianne("marauroa.ath.cx",3214) paintStatusArea("Connecting to server...") text = "" history_lines = [] if pyarianne.login("root777","root777"):

   chars=pyarianne.availableCharacters()
   paintStatusArea("Logged in, choosing character "+chars[0]+"...")
   if pyarianne.chooseCharacter(chars[0]):
       paintStatusArea("Choosed character "+chars[0])
       exit = False
       repaintInputArea()
       while True:
           time.sleep(0.2)
           if pyarianne.hasPerception():
               perception=pyarianne.getPerception()
               perceptionHandler.applyPerception(perception, world)
               printChatMessage(world)
           ch = inputArea.getch()
           if ch != curses.ERR :
              if ch == 10 or ch == curses.KEY_ENTER: #enter
                 if text == "/quit":
                    break
                 if text != "":
                    sendMessage([text])
                 text = ""
              else:
                 text = text + str(chr(ch))
              repaintInputArea()
       pyarianne.logout()
   else:
       paintStatusArea("CAN'T CHOOSE: "+pyarianne.errorReason())

else:

   paintStatusArea("CAN'T LOGIN: "+pyarianne.errorReason())

paintStatusArea("Finishing pyclient") uninitCurses(1,2)

</verbatim>

And here you can see how it looks: [1]