⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psmclient.py

📁 在客户端和服务器架构中
💻 PY
📖 第 1 页 / 共 2 页
字号:
"""
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 + -