📄 psmclient.py
字号:
"""
psmclient.py - PSM Demo Client
A client to demonstrate the concept of Parallel-state machines
"""
import sys
import os
path, ignored = os.path.split(os.getcwd())
sys.path.append(path)
import actor
import socket
import select
import threading
import struct
import string
import shared.characterstatemgr
import shared.moveforward as _moveforward
import shared.moveleft as _moveleft
import shared.movebackward as _movebackward
import shared.moveright as _moveright
import shared.stopped as _stopped
import shared.standing as _standing
import shared.sitting as _sitting
import shared.layingdown as _layingdown
import shared.dead as _dead
import shared.idle as _idle
import shared.casting as _casting
import shared.fighting as _fighting
import shared.crafting as _crafting
import shared.gesturing as _gesturing
from shared.msgtypes import *
# globals
g_actorId = None # id assigned by server for this clients actor
g_actorDict = {} # mapping between actorId and actor instance
g_userInput = 0 # flag indicating whether user input occured
g_inputValue = None # the actual input value
g_port = 4701 # default port the server listens on
g_serverName = 'localhost' # default server to connect to
g_programName = 'PSM Client: '
g_inputPrompt = g_programName+'states=[w,a,s,d,x] [c,v,b] [i,u,y,o,p], 9=status, h=help, 0=exit'
def _ParseStateName(state):
"""
Return a more readable name from the module itself
"""
return state.__name__[7:]
def _GetInput():
"""
Loop reading the console for input. Returns
when input signals to exit
"""
global g_userInput
global g_inputValue
while 1:
c = sys.stdin.read(1)
if c in ['w','a','s','d','x','c','v','b','y','u','i','o','p','9','h']:
a = threading.Lock()
a.acquire()
g_userInput = 1
g_inputValue = c
a.release()
elif c == '0':
return
def _RequestStateChange(s, stateToRequest):
"""
Processes the state change request by the user.
finds to local actor instance and then requests
the specified state change on the actor itself.
if succesful, make the request to the server,
otherwise report the failure
"""
actor = g_actorDict[g_actorId]
if actor.RequestStateChange(stateToRequest):
print g_programName+'Transitioned to state [%s], sending server request' % (_ParseStateName(stateToRequest),)
print '(L)Actor %s: Posture [%s] Movement [%s] Action [%s]' % (g_actorId,
_ParseStateName(actor.GetPostureState()), \
_ParseStateName(actor.GetMovementState()), \
_ParseStateName(actor.GetActionState()))
data = struct.pack("<BB", MSG_TYPE_STATE_CHANGE_REQUEST, stateToRequest.GetStateId())
s.send(data)
else:
print g_programName+'Blocked from transitioning to state [%s]' % (_ParseStateName(stateToRequest),)
print '(L)Actor %s: Posture [%s] Movement [%s] Action [%s]' % (g_actorId,
_ParseStateName(actor.GetPostureState()), \
_ParseStateName(actor.GetMovementState()), \
_ParseStateName(actor.GetActionState()))
print ''
print g_inputPrompt
def _ActorStatus(s):
"""
Displays this clients current states for each actor,
tagging the local actor with an "(L)"
"""
print ''
print 'Actor Status'
print '-----------------------------------------------------------------------------'
for actorId, actor in g_actorDict.items():
if g_actorId == actorId:
print '(L)Actor %s: Posture [%s] Movement [%s] Action [%s]' % (actorId, _ParseStateName(actor.GetPostureState()), \
_ParseStateName(actor.GetMovementState()), \
_ParseStateName(actor.GetActionState()))
else:
print ' Actor %s: Posture [%s] Movement [%s] Action [%s]' % (actorId, _ParseStateName(actor.GetPostureState()), \
_ParseStateName(actor.GetMovementState()), \
_ParseStateName(actor.GetActionState()))
print '-----------------------------------------------------------------------------'
print ''
print g_inputPrompt
def _ShowHelp(s):
"""
prints extended help
"""
print 'Press the specified key and [Enter] to cause the local actor to transition to'
print 'the state desired. If valid to do so in the current state, a request is sent to'
print 'the server. The resulting local actor state is displayed after each request.'
print ''
print 'Options: Movement Posture Action'
print ' ================= ======= ======'
print ' w = moveforward c = standing i = idle'
print ' a = moveleft v = sitting u = casting'
print ' s = movebackward b = layingdown y = crafting'
print ' d = moveright o = fighting'
print ' x = stopped p = gesturing'
print ''
print 'Two actions are given additional functionality if there is more that 1 client'
print 'connected. Select casting "u" will attempt to cast a FREEZE spell on another'
print 'actor. If successfull, it will render the affected actor unable to move.'
print 'Selecting fighting "f" will cause an actor to attack another actor. The fight'
print 'is to the death, and the initiator of the attack has a hihger probability of'
print 'success. If the initiator loses he himself will die.'
print ''
print 'Entering "9" causes the display of an overall status of each actor'
print 'that is connected; an actor is assigned to each client that is logged in.'
print 'The actor aasociated with a client is tagged with an (L). "0" exits.'
print ''
print g_inputPrompt
"""
This global shows up here so that we can use the
direct method reference in the dictionary.
"""
g_methodDict = {
# input method args
# ---- ------- -----
'w' : (_RequestStateChange, (_moveforward,)),
'a' : (_RequestStateChange, (_moveleft,)),
's' : (_RequestStateChange, (_movebackward,)),
'd' : (_RequestStateChange, (_moveright,)),
'x' : (_RequestStateChange, (_stopped,)),
'c' : (_RequestStateChange, (_standing,)),
'v' : (_RequestStateChange, (_sitting,)),
'b' : (_RequestStateChange, (_layingdown,)),
'i' : (_RequestStateChange, (_idle,)),
'u' : (_RequestStateChange, (_casting,)),
'y' : (_RequestStateChange, (_crafting,)),
'o' : (_RequestStateChange, (_fighting,)),
'p' : (_RequestStateChange, (_gesturing,)),
'9' : (_ActorStatus, ()),
'h' : (_ShowHelp, ()),
}
def _InvokeMethod(input, s):
"""
Utility method that inovokes the appropriate
method doing a lookup based on user input.
Any args specified are passed through to
the method.
"""
global g_methodDict
if g_methodDict.has_key(input):
method, args = g_methodDict[input]
# print 'method to call is %s with %s' % (method,s)
apply(method, (s,)+args)
def Recv_ActorLeft(data):
"""
A client disconnected from the server. Remove
that actor from this clients lookup so that is
in sync with the servers actors.
"""
global g_actorDict
(actorId,) = struct.unpack("<B", data[0])
assert g_actorId != actorId, 'server telling us we left!'
print g_programName+'actor left, id is %s' % (actorId,)
del g_actorDict[actorId]
print g_inputPrompt
return data[1:]
def Recv_NewActor(data):
"""
A new client logged into the server. Add it to
our actor lookup and set the initial states to those
specified on the server
"""
global g_actorDict
newActorId, p, m, a = struct.unpack("<BBBB", data[0:4])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -