Python以TCp搭建小游戏服务器

#coding=UTF-8
‘’’
任务:密室逃脱(猜数字)服务器
作者:全淅亚
时间:2019.7.14
‘’’

import SocketServer
import random,time
import base64
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex

playNum = 0 #在线人数
playName = {} #玩家名字

bestNum = 0 #竞赛模式
coop = 0
rank = []

生成4位数

def secretRandom():
print ‘生成随机不重复4位数’
randomNum = range(0, 10)
random.shuffle(randomNum)
# print ‘测试生成0-9随机数’,randomNum
global secret
secret = str(randomNum[0] * 1000 + randomNum[1] * 100 + randomNum[2] * 10 + randomNum[3])
print ‘测试生成4位数密码数字序列’,secret
return secret

class MyTCPHandler(SocketServer. BaseRequestHandler): # 必须写入handle方法,建立链接时会自动执行handle方法
def handle(self):
global playNum
playNum += 1
try:
print ‘连接到客户端:’, self.client_address
print ‘目前在线玩家:’, playNum
print ‘发送游戏介绍’
self.AES(msg=self. gameBg(), s=1)
self.AES(msg=self.gameIntro(), s=1)
time.sleep(1)
self.playName()
self.pattern()
self.playExit()
except:
print ‘客户端’, self.client_address, ‘断开连接’
# 开始游戏
def playGame(self):
print self.client_address,‘开始游戏’
self.AES(msg=self.gamePlay(), s=1)
while True:
data = self.AES(msg=’’, s=2)
# 信息判断
if self.order(data):
continue
if self.inputError(data):
continue
if self.backInfo(data) == ‘4A0B’:
break

#创建游戏名
def playName(self):
    self.AES(msg='输入您的游戏名称:', s=1)
    temp = self.AES(msg='', s=2)
    print temp,'进入游戏'
    global playName
    playName[self.client_address] = temp


#选择模式
def pattern(self):
    while True:
        self.AES(msg='选择模式(输入1/2):\n1.单人模式\n2.竞赛模式', s=1)
        temp = self.AES(msg='', s=2)
        if temp == '1':
            print self.client_address, '选择单人模式'
            self.playGame()
            self.AES(msg='游戏结束,恭喜您猜对了!^_^\n输入 是 开始新游戏,输入其他退出游戏', s=1)
            self.endGame()
        if temp == '2':
            print self.client_address, '选择竞赛模式'
            global coop
            coop += 1
            while True:
                if coop >=2:
                    self.tellPlay()
                    self.playGame()
                    self.tellEnd()
                    self.endGame()
                else:
                    self.AES(msg='等待玩家加入...', s=1)
                    time.sleep(2)
        else:
            self.AES(msg='输入错误', s=1)
            continue
#通告玩家开始竞赛
def tellPlay(self):
    global playName
    msg = ''
    for i in playName:
        msg = msg +'玩家%s进入竞赛模式\n'%playName[i]
    self.AES(msg=msg, s=1)

#通告玩家竞赛结束
def tellEnd(self):
    rank.append(playName[self.client_address])
    msg = ''
    for i in range(len(rank)):
        x = i + 1
        print x
        msg = msg + rank[i]+'获得%d名\n'%x
    self.AES(msg=msg, s=1)
    self.AES(msg='游戏结束,恭喜您猜对了!^_^\n输入 是 开始新游戏,输入其他退出游戏', s=1)

# 特殊指令判断
def order(self,data):
    print '特殊指令判断'
    if data == 'a':
        self.find()
        return 1
    elif data == 'b':
        self.modify()
        return 1
    elif data == 'c':
        secretRandom()
        print self.client_address,'重置序列成功'
        self.AES(msg='重置序列成功', s=1)
        return 1
    elif data == 'exit':
        self.playExit()

# 输入异常判断
def inputError(self,data):
    print '输入异常判断'
    try:
        int(data)
    except:
        self.AES(msg='输入非法字符,请输入数字!', s=1)
        return 1
    if len(data) != 4:
        self.AES(msg='请输入4位数!!', s=1)
        return 1


# 反馈信息
def backInfo(self,data):
    print '反馈信息'
    A, B = 0, 0
    for x in range(0, 4):
        if data[x] == secret[x]:
            A = A + 1
        else:
            for y in range(0, 4):
                if data[x] == secret[y]:
                    B = B + 1
    msg ='%dA%dB'%(A,B)
    self.AES(msg=msg, s=1)
    return msg

# 查询序列
def find(self):
    print self.client_address,'查询序列'
    msg = '数字序列:%s\n'%secret
    self.AES(msg=msg, s=1)

# 修改序列
def modify(self):
    while True:
        print self.client_address,'修改序列'
        self.AES(msg='输入修改后的序列:', s=1)
        data = self.AES(msg='', s=2)
        if self.inputError(data):
            continue
        global secret
        secret = data
        self.AES(msg='修改成功', s=1)
        break

#游戏结束
def endGame(self):
    data = self.AES(msg='', s=2)
    if data == '是':
        print self.client_address,'开始新游戏'
        secretRandom()
        self.pattern()
    else:
        print self.client_address,'退出游戏'
        self.AES(msg='exit',s=1)
        self.playExit()

#退出游戏
def playExit(self):
    global playNum
    playNum += -1
    print '目前在线玩家:', playNum
    self.request.close()

#数据加密解密
def AES(self,msg,s):
    aes_encrypt = AES_ENCRYPT()
    if s == 1:
        print '数据加密'
        msg = aes_encrypt.encrypt(msg)
        self.request.sendall(msg)
    if s == 2:
        print '数据解密'
        data = self.request.recv(1024)
        data = aes_encrypt.decrypt(data).strip(b'\x0e')
        return data

def gameBg(self):
    return '''------游戏:密室逃脱!-----

[游戏背景]:
当你从睡梦中苏醒
你惊慌的发现自己被关了起来
这是一个封闭无物的钢铁密室
密室只有一扇电子锁大门
注意!!!
现在你必须保持冷静
大门会随机一个没有重复数字的4位数序列
你只有答对序列才能逃出密室…’’’
def gameIntro(self):
return’’’[玩法介绍]:
你要在界面上输入一个没有重复数字的4位数数字如1234
大门会根据你的答案给出反馈几A几B的提示
其中A前面的数字表示位置正确的数的个数
而B前的数字表示数字正确而位置不对的数的个数’’’

def gamePlay(self):
    return'''[游戏开始]:
    请输入一个没有重复数字的4位数(输入a可以查询序列、b修改序列、c重置序列、exit退出游戏):'''

#AES加密数据密匙
AES_SECRET_KEY = ‘B31F2A75FBF94099’ #此处16|24|32个字符
IV = “1234567890123456”
#数据加密类
class AES_ENCRYPT(object):
def init(self):
self.key = AES_SECRET_KEY
self.mode = AES.MODE_CBC

#加密函数
def encrypt(self, text):
    cryptor = AES.new(self.key, self.mode,IV)
    length = 16
    count = len(text)
    if count < length:
        add = (length - count)
        # \0 backspace
        text = text + ('\0' * add)
    elif count > length:
        add = (length - (count % length))
        text = text + ('\0' * add)
    self.ciphertext = cryptor.encrypt(text)
    #AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题,使用base64编码
    return b2a_hex(self.ciphertext)

#解密函数
def decrypt(self, text):
    cryptor = AES.new(self.key, self.mode,IV)
    plain_text = cryptor.decrypt(a2b_hex(text))
    return plain_text.rstrip('\0')

if name == ‘main’:
secretRandom()
print ‘等待客户端连接…’
server = SocketServer.ThreadingTCPServer((‘127.0.0.1’, 8080), MyTCPHandler)
server.serve_forever() # 链接循环

你可能感兴趣的:(python,python后台工程师,服务器客户端)