From 0ad0d0df34a8f95561724ad0b0b40a1d132dc161 Mon Sep 17 00:00:00 2001 From: nv Date: Sun, 9 Jul 2017 09:09:08 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AE=80=E5=8D=95=E6=B3=A8=E5=86=8C=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- schema.sql | 4 +- src/core/player.py | 9 +- src/core/robot.py | 1 + src/core/room.py | 9 +- src/core/table.py | 4 +- src/net/base.py | 34 +++++++ src/net/socket.py | 26 +++-- src/net/web.py | 54 +++------- src/static/i/btn/register.png | Bin 0 -> 2404 bytes src/static/js/boot.js | 183 +++++++++++++--------------------- src/static/js/game.js | 24 +++-- src/static/poker.html | 4 +- 13 files changed, 166 insertions(+), 188 deletions(-) create mode 100644 src/net/base.py create mode 100644 src/static/i/btn/register.png diff --git a/README.md b/README.md index 5f1531e..1301941 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ 运行: -pip3 install tornado bcrypt pymysql +pip3 install tornado bcrypt pymysql msgpack python3 main.py diff --git a/schema.sql b/schema.sql index 3a19b23..52b34cf 100644 --- a/schema.sql +++ b/schema.sql @@ -4,9 +4,9 @@ CREATE DATABASE IF NOT EXISTS ddz DEFAULT CHARSET utf8 COLLATE utf8_general_ci; CREATE TABLE IF NOT EXISTS account ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, - email VARCHAR(16) NOT NULL UNIQUE, + email VARCHAR(20) NOT NULL UNIQUE, username VARCHAR(10) NOT NULL, - password VARCHAR(32) NOT NULL, + password VARCHAR(100) NOT NULL, coin INT default 4000, created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); diff --git a/src/core/player.py b/src/core/player.py index 6e064b6..6933c04 100644 --- a/src/core/player.py +++ b/src/core/player.py @@ -13,7 +13,7 @@ class Player(object): - def __init__(self, uid: int, name: str, socket: WebSocketHandler=None): + def __init__(self, uid: int, name: str, socket: WebSocketHandler = None): from core.table import Table self.uid = uid self.name = name @@ -95,8 +95,11 @@ def join_table(self, t): def leave_table(self): self.ready = False if self.table: - self.table.remove(self) - logger.info('Player[%d] leave Table[%d]', self.uid, self.table.uid) + self.table.remove(self) + logger.info('Player[%d] leave Table[%d]', self.uid, self.table.uid) + + def __repr(self): + return self.__str__() def __str__(self): return self.uid + '-' + self.name diff --git a/src/core/robot.py b/src/core/robot.py index c1a3e40..d5b1dc6 100644 --- a/src/core/robot.py +++ b/src/core/robot.py @@ -70,3 +70,4 @@ def auto_shot_poker(self): packet = [Pt.REQ_SHOT_POKER, pokers] # IOLoop.current().add_callback(self.to_server, packet) IOLoop.current().call_later(2, self.to_server, packet) + diff --git a/src/core/room.py b/src/core/room.py index 81d320a..2dbd6ce 100644 --- a/src/core/room.py +++ b/src/core/room.py @@ -25,7 +25,7 @@ def find_waiting_table(self, uid, default=None): def first_waiting_table(self): for _, table in self.waiting_tables.items(): return table - t = Table() + t = Table(self) self.waiting_tables[t.uid] = t return t @@ -61,12 +61,15 @@ def playing_tables(self): class RoomManager(object): __metaclass__ = Singleton - __room_dict = {} + __room_dict = { + 1: Room(1, True), + 2: Room(2, False), + } @staticmethod def find_room(uid, created=False): room = RoomManager.__room_dict.get(uid) if not room and created: - room = Room(0) + room = Room(uid) RoomManager.__room_dict[uid] = room return room diff --git a/src/core/table.py b/src/core/table.py index 82ac471..684decf 100644 --- a/src/core/table.py +++ b/src/core/table.py @@ -39,11 +39,11 @@ def ai_join(self, nth=1): if size == 2 and nth == 1: IOLoop.current().call_later(1, self.ai_join, nth=2) - p1 = AiPlayer(11, 'AI-1', self.players[0]) + p1 = AiPlayer(11, 'IDIOT-I', self.players[0]) p1.to_server([Pt.REQ_JOIN_TABLE, self.uid]) if size == 1: - p2 = AiPlayer(12, 'AI-2', self.players[0]) + p2 = AiPlayer(12, 'IDIOT-II', self.players[0]) p2.to_server([Pt.REQ_JOIN_TABLE, self.uid]) def sync_table(self): diff --git a/src/net/base.py b/src/net/base.py new file mode 100644 index 0000000..1e9d98e --- /dev/null +++ b/src/net/base.py @@ -0,0 +1,34 @@ +from concurrent.futures import ThreadPoolExecutor + +from tornado.escape import json_encode +from tornado.web import RequestHandler + +from db import torndb + + +class BaseHandler(RequestHandler): + + @property + def db(self) -> torndb.Connection: + return self.application.db + + @property + def executor(self) -> ThreadPoolExecutor: + return self.application.executor + + def data_received(self, chunk): + pass + + def get_current_user(self): + return self.get_secure_cookie("user") + + def set_current_user(self, uid, username): + info = { + 'uid': uid, + 'username': username, + } + self.set_secure_cookie('user', json_encode(info)) + + def on_finish(self): + # self.session.flush() + pass diff --git a/src/net/socket.py b/src/net/socket.py index 43d09b9..caa256b 100644 --- a/src/net/socket.py +++ b/src/net/socket.py @@ -3,6 +3,8 @@ import logging import msgpack +from tornado.escape import json_decode +from tornado.web import authenticated from tornado.websocket import WebSocketHandler, WebSocketClosedError from core.player import Player @@ -33,6 +35,9 @@ def __init__(self, application, request, **kwargs): def data_received(self, chunk): logger.info('socket data_received') + def get_current_user(self): + return json_decode(self.get_secure_cookie("user")) + @property def uid(self): return self.player.uid @@ -41,9 +46,10 @@ def uid(self): def room(self): return self.player.room + @authenticated def open(self): - self.player = Player(10, 'Jerry', self) - self.player.room = RoomManager.find_room(0, True) + user = self.current_user + self.player = Player(user['uid'], user['username'], self) logger.info('SOCKET[%s] OPEN', self.player.uid) def on_message(self, message): @@ -57,19 +63,20 @@ def on_message(self, message): self.write_message(response) elif code == Pt.REQ_ROOM_LIST: - response = [Pt.RSP_ROOM_LIST] - self.write_message(response) + self.write_message([Pt.RSP_ROOM_LIST]) elif code == Pt.REQ_TABLE_LIST: - response = [Pt.RSP_TABLE_LIST, self.room.tables()] - self.write_message(response) + self.write_message([Pt.RSP_TABLE_LIST, self.room.tables()]) + + elif code == Pt.REQ_JOIN_ROOM: + self.player.room = RoomManager.find_room(packet[1]) + self.write_message([Pt.RSP_JOIN_ROOM]) elif code == Pt.REQ_JOIN_TABLE: table_id = packet[1] table = self.find_table(table_id) if not table: - response = [Pt.RSP_TABLE_LIST, self.room.tables()] - self.write_message(response) + self.write_message([Pt.RSP_TABLE_LIST, self.room.tables()]) logger.info('PLAYER[%d] JOIN FULL TABLE[%d]', self.uid, table.uid) self.player.join_table(table) @@ -125,9 +132,8 @@ def write_message(self, message, binary=False): return self.ws_connection.write_message(packet, binary=binary) def on_close(self): - # self.session.get(self.uid).socket = None - logger.info('socket[%s] close', self.player.uid) if self.player: + logger.info('socket[%s] close', self.player.uid) self.player.leave_table() def send_updates(cls, chat): diff --git a/src/net/web.py b/src/net/web.py index 1f6b2f0..b766112 100644 --- a/src/net/web.py +++ b/src/net/web.py @@ -1,45 +1,21 @@ -import json import subprocess -from concurrent.futures import ThreadPoolExecutor import bcrypt -import tornado.escape -import tornado.httpserver -import tornado.ioloop -import tornado.options -import tornado.web -from tornado.web import RequestHandler -from db import torndb -from core.player import Player - - -class BaseHandler(RequestHandler): - @property - def db(self) -> torndb.Connection: - return self.application.db - - @property - def executor(self) -> ThreadPoolExecutor: - return self.application.executor - - def data_received(self, chunk): - pass - - def on_finish(self): - # self.session.flush() - pass +from net.base import BaseHandler class WebHandler(BaseHandler): - # @tornado.web.authenticated def get(self): if not self.get_cookie("_csrf"): self.set_cookie("_csrf", self.xsrf_token) - self.render('poker.html') + # user = xhtml_escape(self.current_user or '') + user = self.current_user or '' + self.render('poker.html', user=user) class UpdateHandler(BaseHandler): + # @tornado.web.authenticated def get(self): proc = subprocess.run(["git", "pull"], stdout=subprocess.PIPE) self.head('content-type', 'text/plain; charset=UTF-8') @@ -51,8 +27,10 @@ class RegHandler(BaseHandler): def post(self): email = self.get_argument('email', self.get_argument('username')) account = self.db.get('SELECT * FROM account WHERE email="%s"', email) + if account: - raise tornado.web.HTTPError(400, "username already taken") + self.write('1') + return username = self.get_argument('username') password = self.get_argument('password') @@ -61,28 +39,26 @@ def post(self): uid = self.db.insert('INSERT INTO account (email, username, password) VALUES ("%s", "%s", "%s")', email, username, password) - self.set_secure_cookie("uid", str(account.get('id'))) - self.write('ok') + self.set_current_user(uid, username) + self.write('0') class LoginHandler(BaseHandler): def post(self): - username = self.get_argument('email') + email = self.get_argument('email') password = self.get_argument("password") - account = self.db.get('SELECT * FROM account WHERE email="%s"', self.get_argument('email')) + account = self.db.get('SELECT * FROM account WHERE email="%s"', email) password = bcrypt.hashpw(password.encode('utf8'), account.get('password')) self.head('content-type', 'application/json') if password == account.get('password'): - self.set_secure_cookie("uid", str(account.get('id'))) + self.set_current_user(account.get('id'), account.get('username')) self.redirect(self.get_argument("next", "/")) -class LoginoutHandler(BaseHandler): +class LogoutHandler(BaseHandler): def post(self): - uid = self.get_secure_cookie("uid") - self.clear_cookie("uid") - self.session.remove(int(uid)) + self.clear_cookie('user') self.redirect(self.get_argument("next", "/")) diff --git a/src/static/i/btn/register.png b/src/static/i/btn/register.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3e675791d6861f1ae17d667e5ac9b2e730fd61 GIT binary patch literal 2404 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 - +
-{% module xsrf_form_html() %} +