Implement "password"-based session joining.

This commit is contained in:
Danila Fedorin 2018-05-25 15:29:22 -07:00
parent f01c891cec
commit 75a386539e
5 changed files with 46 additions and 31 deletions

2
external/GoUI vendored

@ -1 +1 @@
Subproject commit 0d31433b96e1f7e656243a44eaed97b01f8f7d80 Subproject commit 4acfc0911a8864c517cb23712c76cddcbc561e69

View File

@ -9550,10 +9550,7 @@ var _user$project$Go_Ws$wsUrl = function (m) {
return A2( return A2(
_elm_lang$core$Basics_ops['++'], _elm_lang$core$Basics_ops['++'],
m.sessionUrl, m.sessionUrl,
A2( A2(_elm_lang$core$Basics_ops['++'], '/game/', m.sessionId));
_elm_lang$core$Basics_ops['++'],
'/game/',
_elm_lang$core$Basics$toString(m.sessionId)));
}; };
var _user$project$Go_Ws$sendMove = F2( var _user$project$Go_Ws$sendMove = F2(
function (m, c) { function (m, c) {
@ -9655,7 +9652,7 @@ var _user$project$Main$initDummy = {
_user$project$Go_Types$Model, _user$project$Go_Types$Model,
_user$project$Go_Types$Black, _user$project$Go_Types$Black,
'ws://localhost:3000', 'ws://localhost:3000',
1, 'debug',
9, 9,
_elm_lang$core$Maybe$Nothing, _elm_lang$core$Maybe$Nothing,
_elm_lang$core$Maybe$Nothing, _elm_lang$core$Maybe$Nothing,
@ -9698,7 +9695,7 @@ var _user$project$Main$main = _elm_lang$html$Html$programWithFlags(
}, },
A2(_elm_lang$core$Json_Decode$field, 'size', _elm_lang$core$Json_Decode$int)); A2(_elm_lang$core$Json_Decode$field, 'size', _elm_lang$core$Json_Decode$int));
}, },
A2(_elm_lang$core$Json_Decode$field, 'id', _elm_lang$core$Json_Decode$int)); A2(_elm_lang$core$Json_Decode$field, 'id', _elm_lang$core$Json_Decode$string));
}, },
A2(_elm_lang$core$Json_Decode$field, 'black', _elm_lang$core$Json_Decode$bool))); A2(_elm_lang$core$Json_Decode$field, 'black', _elm_lang$core$Json_Decode$bool)));

View File

@ -3,12 +3,22 @@ require "kemal"
require "json" require "json"
URL = "localhost" URL = "localhost"
GAME_CACHE = {} of Int64 => Go::Game GAME_CACHE = {} of String => Go::Game
def lookup_game(cache, id) : Go::Game? def query_game(db, id) : Go::Game?
return nil return nil
end end
def lookup_game(db, cache, id) : Go::Game?
if game = cache[id]?
return game
else
loaded_game = query_game(db, id)
cache[id] = loaded_game if loaded_game
return loaded_game
end
end
def handle_message(id, game, socket, message) def handle_message(id, game, socket, message)
split_command = message.split(" ") split_command = message.split(" ")
command = split_command[0] command = split_command[0]
@ -27,41 +37,43 @@ get "/" do |env|
end end
get "/game/:id" do |env| get "/game/:id" do |env|
if game_id = env.params.url["id"].to_i64? game_id = env.params.url["id"]
if game = (GAME_CACHE[game_id]? || lookup_game(GAME_CACHE, game_id)) game_password = env.params.query["password"]?
if game = lookup_game(nil, GAME_CACHE, game_id)
id = game_id
size = game.size.value
black = nil
if game_password == game.blackPass
black = true black = true
id = game_id elsif game_password == game.whitePass
size = game.size.value black = false
render "src/Go/views/game.ecr"
else
render_404
end end
black.try { |black| render "src/Go/views/game.ecr"} || render_404
else else
render_404 render_404
end end
end end
ws "/game/:id" do |socket, env| ws "/game/:id" do |socket, env|
if game_id = env.params.url["id"].to_i64? game_id = env.params.url["id"]
if game = (GAME_CACHE[game_id]? || lookup_game(GAME_CACHE, game_id)) if game = lookup_game(nil, GAME_CACHE, game_id)
socket.send game.to_string socket.send game.to_string
game.sockets << socket game.sockets << socket
socket.on_message do |message| socket.on_message do |message|
game.try { |game| handle_message(game_id, game, socket, message) } game.try { |game| handle_message(game_id, game, socket, message) }
end end
socket.on_close do socket.on_close do
game.try { |game| game.sockets.delete socket } game.try { |game| game.sockets.delete socket }
end
else
render_404
end end
else else
render_404 render_404
end end
end end
GAME_CACHE[1_i64] = Go::Game.new(Go::Size::Small) GAME_CACHE["debug"] = Go::Game.new(Go::Size::Small, "black", "white")
Kemal.run Kemal.run

View File

@ -14,11 +14,13 @@ module Go
class Game class Game
property size : Size property size : Size
property blackPass : String
property whitePass : String
property board : Board property board : Board
property turn : Color property turn : Color
property sockets : Array(HTTP::WebSocket) property sockets : Array(HTTP::WebSocket)
def initialize(size : Size) def initialize(size : Size, @blackPass, @whitePass)
@size = size @size = size
@board = Board.new @board = Board.new
@turn = Color::Black @turn = Color::Black
@ -56,6 +58,7 @@ module Go
def update(x, y, color) def update(x, y, color)
@board[{x, y}] = color @board[{x, y}] = color
@turn = @turn == Color::Black ? Color::White : Color::Black
end end
private def color_char(color) private def color_char(color)

View File

@ -9,6 +9,9 @@
.black-cell { .black-cell {
background-color: black; background-color: black;
} }
.white-cell {
background-color: white;
}
.board { .board {
max-width: 360px; max-width: 360px;
} }
@ -22,7 +25,7 @@
var app = Elm.Main.embed(node, { var app = Elm.Main.embed(node, {
'black' : <%= black %>, 'black' : <%= black %>,
'url' : "<%= "ws://" + URL + ":" + Kemal.config.port.to_s %>", 'url' : "<%= "ws://" + URL + ":" + Kemal.config.port.to_s %>",
'id' : <%= id %>, 'id' : "<%= id %>",
'size' : <%= size %> 'size' : <%= size %>
}) })
</script> </script>