ChatdServerClientExample: Difference between revisions
imported>Merlin No edit summary |
imported>Merlin No edit summary |
(No difference)
| |
Revision as of 21:05, 20 April 2008
The information on this page is mainly outdated. You can find a draft version of client/server chat example based on Marauroa 2.5 at ClientServerChatExample.
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.
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)
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
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()
#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)
And here you can see how it looks: