#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 = []
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() # 链接循环