[Bug Fix][Enhance] About Link Play

- Fix a bug that the room host will be changed late when finishing a song
- Add logging module for linkplay server
This commit is contained in:
Lost-MSth
2022-09-19 23:13:51 +08:00
parent 6298b37ea2
commit 299c8c582c
9 changed files with 52 additions and 41 deletions

View File

@@ -37,13 +37,13 @@ class Constant:
DOWNLOAD_TIME_GAP_LIMIT = Config.DOWNLOAD_TIME_GAP_LIMIT
DOWNLOAD_LINK_PREFIX = Config.DOWNLOAD_LINK_PREFIX
LINK_PLAY_UNLOCK_LENGTH = 512 # Units: bytes
LINK_PLAY_TIMEOUT = 5 # Units: seconds
LINKPLAY_UNLOCK_LENGTH = 512 # Units: bytes
LINKPLAY_TIMEOUT = 5 # Units: seconds
LINK_PLAY_HOST = '127.0.0.1' if Config.SET_LINK_PLAY_SERVER_AS_SUB_PROCESS else Config.LINK_PLAY_HOST
LINK_PLAY_TCP_PORT = Config.LINK_PLAY_TCP_PORT
LINK_PLAY_UDP_PORT = Config.LINK_PLAY_UDP_PORT
LINK_PLAY_AUTHENTICATION = Config.LINK_PLAY_AUTHENTICATION
LINKPLAY_HOST = '127.0.0.1' if Config.SET_LINKPLAY_SERVER_AS_SUB_PROCESS else Config.LINKPLAY_HOST
LINKPLAY_TCP_PORT = Config.LINKPLAY_TCP_PORT
LINKPLAY_UDP_PORT = Config.LINKPLAY_UDP_PORT
LINKPLAY_AUTHENTICATION = Config.LINKPLAY_AUTHENTICATION
COURSE_STAMINA_COST = 4

View File

@@ -6,14 +6,14 @@ from core.error import ArcError, Timeout
from .constant import Constant
from .user import UserInfo
socket.setdefaulttimeout(Constant.LINK_PLAY_TIMEOUT)
socket.setdefaulttimeout(Constant.LINKPLAY_TIMEOUT)
def get_song_unlock(client_song_map: dict) -> bytes:
'''处理可用歌曲bit返回bytes'''
user_song_unlock = [0] * Constant.LINK_PLAY_UNLOCK_LENGTH
for i in range(0, Constant.LINK_PLAY_UNLOCK_LENGTH*2, 2):
user_song_unlock = [0] * Constant.LINKPLAY_UNLOCK_LENGTH
for i in range(0, Constant.LINKPLAY_UNLOCK_LENGTH*2, 2):
x = 0
y = 0
if str(i) in client_song_map:
@@ -98,8 +98,8 @@ class RemoteMultiPlayer:
@staticmethod
def tcp(data: str) -> str:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((Constant.LINK_PLAY_HOST,
Constant.LINK_PLAY_TCP_PORT))
sock.connect((Constant.LINKPLAY_HOST,
Constant.LINKPLAY_TCP_PORT))
sock.sendall(bytes(data + "\n", "utf-8"))
try:
received = str(sock.recv(1024), "utf-8").strip()
@@ -111,7 +111,7 @@ class RemoteMultiPlayer:
def data_swap(self, data: tuple) -> tuple:
received = self.tcp(Constant.LINK_PLAY_AUTHENTICATION +
received = self.tcp(Constant.LINKPLAY_AUTHENTICATION +
'|' + '|'.join([str(x) for x in data]))
self.data_recv = received.split('|')

View File

@@ -1,6 +1,3 @@
from telnetlib import AUTHENTICATION
class Config:
'''
Link Play server configuration

View File

@@ -1,4 +1,5 @@
import base64
import logging
import random
import socketserver
import threading
@@ -19,6 +20,9 @@ player_dict = {} # 'player_id' : Player
clean_timer = 0
lock = threading.RLock()
logging.basicConfig(format='[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
level=logging.INFO)
def random_room_code():
# 随机生成房间号
@@ -102,7 +106,7 @@ class UDP_handler(socketserver.BaseRequestHandler):
plaintext = decrypt(user['key'], b'', iv, ciphertext, tag)
except Exception as e:
print(e)
logging.error(e)
return None
# print(binascii.b2a_hex(plaintext))
@@ -135,11 +139,14 @@ class TCP_handler(socketserver.StreamRequestHandler):
data = message.split('|')
if data[0] != Config.AUTHENTICATION:
self.wfile.write(b'No authentication')
logging.warning('TCP-%s-No authentication' %
self.client_address[0])
return None
global clean_timer
now = round(time.time() * 1000)
if now - clean_timer >= Config.TIME_LIMIT:
logging.info('Start cleaning memory...')
clean_timer = now
memory_clean(now)
@@ -186,6 +193,7 @@ def data_swap(data: list) -> str:
'player_index': 0,
'player_id': player_id}
logging.info('TCP-Create room `%s` by player `%s`' % (room_code, name))
return '|'.join([str(x) for x in (0, room_code, room_id, token, base64.b64encode(key).decode('utf-8'), player_id)])
elif data[0] == '2':
@@ -230,6 +238,7 @@ def data_swap(data: list) -> str:
'player_index': player_index,
'player_id': player_id}
logging.info('TCP-Player `%s` joins room `%s`' % (name, room_code))
return '|'.join([str(x) for x in (0, room_code, room.room_id, token, base64.b64encode(key).decode('utf-8'), player_id, base64.b64encode(room.song_unlock).decode('utf-8'))])
elif data[0] == '3':
@@ -238,6 +247,7 @@ def data_swap(data: list) -> str:
token = int(data[1])
if token in link_play_data:
r = link_play_data[token]
logging.info('TCP-Room `%s` info update' % room_code)
return '|'.join([str(x) for x in (0, r['room'].room_code, r['room'].room_id, base64.b64encode(r['key']).decode('utf-8'), r['room'].players[r['player_index']].player_id, base64.b64encode(r['room'].song_unlock).decode('utf-8'))])
else:
return '108'

View File

@@ -230,6 +230,9 @@ class CommandParser:
self.room.countdown = Config.COUNTDOWM_TIME
self.room.timestamp = round(time.time() * 1000)
self.room.state = 4
if self.room.round_switch == 1:
# 将换房主时间提前到此刻
self.room.make_round()
if self.room.state == 4 or self.room.state == 5 or self.room.state == 6:
timestamp = round(time.time() * 1000)
@@ -279,8 +282,6 @@ class CommandParser:
flag_13 = True
self.room.state = 1
self.room.song_idx = 0xffff
if self.room.round_switch == 1:
self.room.make_round()
for i in self.room.players:
i.timer = 0

View File

@@ -142,15 +142,15 @@ def main():
except:
app.logger.warning('Initialization error!')
if Config.LINK_PLAY_HOST and Config.SET_LINK_PLAY_SERVER_AS_SUB_PROCESS:
if Config.LINKPLAY_HOST and Config.SET_LINKPLAY_SERVER_AS_SUB_PROCESS:
from linkplay_server import link_play
process = [Process(target=link_play, args=(
Config.LINK_PLAY_HOST, int(Config.LINK_PLAY_UDP_PORT), int(Config.LINK_PLAY_TCP_PORT)))]
Config.LINKPLAY_HOST, int(Config.LINKPLAY_UDP_PORT), int(Config.LINKPLAY_TCP_PORT)))]
[p.start() for p in process]
app.logger.info("Link Play UDP server is running on " +
Config.LINK_PLAY_HOST + ':' + str(Config.LINK_PLAY_UDP_PORT) + " ...")
Config.LINKPLAY_HOST + ':' + str(Config.LINKPLAY_UDP_PORT) + " ...")
app.logger.info("Link Play TCP server is running on " +
Config.LINK_PLAY_HOST + ':' + str(Config.LINK_PLAY_TCP_PORT) + " ...")
Config.LINKPLAY_HOST + ':' + str(Config.LINKPLAY_TCP_PORT) + " ...")
tcp_server_run()
[p.join() for p in process]
else:

View File

@@ -1,2 +1,2 @@
flask>=2.0.2
cryptography
cryptography>=35.0.0

View File

@@ -14,7 +14,7 @@ bp = Blueprint('multiplayer', __name__, url_prefix='/multiplayer')
@auth_required(request)
@arc_try
def room_create(user_id):
if not Config.LINK_PLAY_HOST:
if not Config.LINKPLAY_HOST:
raise ArcError('The link play server is unavailable.', 151, status=404)
with Connect() as c:
@@ -24,8 +24,8 @@ def room_create(user_id):
x.create_room(user)
r = x.to_dict()
r['endPoint'] = request.host.split(
':')[0] if Config.LINK_PLAY_DISPLAY_HOST == '' else Config.LINK_PLAY_DISPLAY_HOST
r['port'] = int(Config.LINK_PLAY_UDP_PORT)
':')[0] if Config.LINKPLAY_DISPLAY_HOST == '' else Config.LINKPLAY_DISPLAY_HOST
r['port'] = int(Config.LINKPLAY_UDP_PORT)
return success_return(r)
@@ -33,7 +33,7 @@ def room_create(user_id):
@auth_required(request)
@arc_try
def room_join(user_id, room_code):
if not Config.LINK_PLAY_HOST:
if not Config.LINKPLAY_HOST:
raise ArcError('The link play server is unavailable.', 151, status=404)
with Connect() as c:
@@ -45,8 +45,8 @@ def room_join(user_id, room_code):
x.join_room(room, user)
r = x.to_dict()
r['endPoint'] = request.host.split(
':')[0] if Config.LINK_PLAY_DISPLAY_HOST == '' else Config.LINK_PLAY_DISPLAY_HOST
r['port'] = int(Config.LINK_PLAY_UDP_PORT)
':')[0] if Config.LINKPLAY_DISPLAY_HOST == '' else Config.LINKPLAY_DISPLAY_HOST
r['port'] = int(Config.LINKPLAY_UDP_PORT)
return success_return(r)
@@ -54,7 +54,7 @@ def room_join(user_id, room_code):
@auth_required(request)
@arc_try
def multiplayer_update(user_id):
if not Config.LINK_PLAY_HOST:
if not Config.LINKPLAY_HOST:
raise ArcError('The link play server is unavailable.', 151, status=404)
with Connect() as c:
@@ -64,6 +64,6 @@ def multiplayer_update(user_id):
x.update_room(user)
r = x.to_dict()
r['endPoint'] = request.host.split(
':')[0] if Config.LINK_PLAY_DISPLAY_HOST == '' else Config.LINK_PLAY_DISPLAY_HOST
r['port'] = int(Config.LINK_PLAY_UDP_PORT)
':')[0] if Config.LINKPLAY_DISPLAY_HOST == '' else Config.LINKPLAY_DISPLAY_HOST
r['port'] = int(Config.LINKPLAY_UDP_PORT)
return success_return(r)

View File

@@ -42,15 +42,18 @@ class Config():
Setting of your link play server
Please ensure that the settings on the side of Link Play server are consistent.
'''
# SET_LINK_PLAY_SERVER_AS_SUB_PROCESS: If it is `True`, the link play server will run with the main server locally at the same time.
SET_LINK_PLAY_SERVER_AS_SUB_PROCESS = True
# LINK_PLAY_HOST: If it is blank, the link play feature will be disabled.
LINK_PLAY_HOST = '0.0.0.0'
LINK_PLAY_UDP_PORT = 10900
LINK_PLAY_TCP_PORT = 10901
LINK_PLAY_AUTHENTICATION = 'my_link_play_server'
# LINK_PLAY_DISPLAY_HOST: If it is blank, the host of link play server for the client will be obtained automatically.
LINK_PLAY_DISPLAY_HOST = ''
# SET_LINKPLAY_SERVER_AS_SUB_PROCESS: 是否同时在本地启动Link Play服务器
# SET_LINKPLAY_SERVER_AS_SUB_PROCESS: If it is `True`, the link play server will run with the main server locally at the same time.
SET_LINKPLAY_SERVER_AS_SUB_PROCESS = True
# LINKPLAY_HOST: 对主服务器来说的Link Play服务器的地址
# LINKPLAY_HOST: The address of the linkplay server based on the main server. If it is blank, the link play feature will be disabled.
LINKPLAY_HOST = '0.0.0.0'
LINKPLAY_UDP_PORT = 10900
LINKPLAY_TCP_PORT = 10901
LINKPLAY_AUTHENTICATION = 'my_link_play_server'
# LINKPLAY_DISPLAY_HOST: 对客户端来说的Link Play服务器地址如果为空则自动获取
# LINKPLAY_DISPLAY_HOST: The address of the linkplay server based on the client. If it is blank, the host of link play server for the client will be obtained automatically.
LINKPLAY_DISPLAY_HOST = ''
'''
--------------------
'''