5 from datetime
import date
8 # Create a Socket.IO server (CORS arg required on server, not locally)
9 MODE
= os
.getenv('RPSLS_MODE')
10 allowed_origin
= 'https://rpsls.auder.net' if MODE
=='production' else '*'
11 sio
= socketio
.Server(cors_allowed_origins
=allowed_origin
)
13 RPSLS_PATH
= os
.getcwd()
14 DB_PATH
= RPSLS_PATH
+ '/db/rpsls.sqlite'
16 searching
= {} #someone seeks a game? (uid + sid)
17 connected
= {} #map uid --> sid (seek stage)
21 """ Triggered at page reload or tab close """
22 global connected
, searching
24 key_idx
= list(connected
.values()).index(sid
)
25 del connected
[list(connected
.keys())[key_idx
]]
27 # If the user didn't seek, no key to find
29 if searching
and searching
["sid"] == sid
:
34 """ When user sends name from /login page """
35 if not re
.match(r
"^[a-zA-Z]{3,}$", data
):
36 sio
.emit("login", {"err": "Name: letters only"}
, room
=sid
)
38 con
= sqlite3
.connect(DB_PATH
)
42 # Always try to insert (new) Users row
43 cur
.execute("insert into Users (name) values (?)", (data
,))
45 except sqlite3
.IntegrityError
as err
:
46 # If fails: user already exists, find its ID
47 if str(err
) == "UNIQUE constraint failed: Users.name":
48 cur
.execute("select id from Users where name = ?", (data
,))
49 uid
= cur
.fetchone()[0]
54 sio
.emit("login", {"name": data, "uid": uid}
, room
=sid
)
58 """ When user click on 'Play' button """
59 global connected
, searching
60 connected
[data
["uid"]] = sid
62 searching
= {"uid": data["uid"], "sid": sid, "name": data["name"]}
64 # Active seek pending: create game
67 con
= sqlite3
.connect(DB_PATH
)
69 today
= (date
.today(),)
70 cur
.execute("insert into Games (created) values (?)", today
)
72 # To room == sid, opponent is me. To my room, it's him/her
74 {"gid":gid, "oppid":opponent["uid"], "oppname":opponent["name"]}
,
77 {"gid":gid, "oppid":data["uid"], "oppname":data["name"]}
,
79 id_list
= [(data
["uid"],gid
), (opponent
["uid"],gid
)]
80 cur
.executemany("insert into Players (uid,gid) values (?,?)", id_list
)
86 """ New move to DB + transmit to opponent """
87 sio
.emit("move", data
, room
=connected
[data
["oppid"]])
88 con
= sqlite3
.connect(DB_PATH
)
90 cur
.execute("insert into Moves (uid,gid,choice,mnum) values (?,?,?,?)",
91 (data
["uid"],data
["gid"],data
["choice"],data
["mnum"]))
96 def inc_pts(sid
, data
):
97 """ Add a point to the player (who won last round) """
98 con
= sqlite3
.connect(DB_PATH
)
100 cur
.execute("update Players set points=points+1 where uid=? and gid=?",
101 (data
["uid"],data
["gid"]))
106 '/': RPSLS_PATH
+ '/index.html',
107 '/rpsls.js': RPSLS_PATH
+ '/rpsls.js',
108 '/favicon.ico': RPSLS_PATH
+ '/favicon.ico',
109 '/assets': RPSLS_PATH
+ '/assets'
112 PORT
= os
.getenv('RPSLS_PORT')
117 # Wrap with a WSGI application
118 app
= socketio
.WSGIApp(sio
, static_files
=static_files
)
119 eventlet
.wsgi
.server(eventlet
.listen(('127.0.0.1', PORT
)), app
)