Merge pull request #1 from albertoxamin/dev

add lobby password logic
This commit is contained in:
Alberto Xamin 2020-11-25 20:54:02 +01:00 committed by GitHub
commit 172a480c92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 85 additions and 24 deletions

15
.github/workflows/dev-image.yml vendored Normal file
View File

@ -0,0 +1,15 @@
name: Docker Images CI
on:
push:
branches: [ dev ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the Unified Docker image
run: docker build . --file Dockerfile --tag albertoxamin/bang:dev
- name: Log into registry
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
- name: Push images
run: docker push albertoxamin/bang:dev

View File

@ -9,12 +9,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Build the Unified Docker image - name: Build the Unified Docker image
run: docker build . --file Dockerfile --tag albertoxamin/bang:latest run: docker build . --file Dockerfile --tag albertoxamin/bang:latest
- name: Build the Backend Docker image
run: cd backend;docker build . --file Dockerfile --tag albertoxamin/bang-backend:latest
- uses: actions/checkout@v2
- name: Build the Frontend Docker image
run: cd frontend;docker build . --file Dockerfile --tag albertoxamin/bang-frontend:latest
- name: Log into registry - name: Log into registry
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
- name: Push images - name: Push images
run: docker push albertoxamin/bang:latest; docker push albertoxamin/bang-backend:latest; docker push albertoxamin/bang-frontend:latest run: docker push albertoxamin/bang:latest

2
.gitignore vendored
View File

@ -136,3 +136,5 @@ dmypy.json
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/
frontend/package-lock.json

View File

@ -1,4 +1,5 @@
import json import json
import random
from typing import List from typing import List
import eventlet import eventlet
import socketio import socketio
@ -17,7 +18,7 @@ games: List[Game] = []
online_players = 0 online_players = 0
def advertise_lobbies(): def advertise_lobbies():
sio.emit('lobbies', room='lobby', data=[{'name': g.name, 'players': len(g.players)} for g in games if not g.started and len(g.players) < 7]) sio.emit('lobbies', room='lobby', data=[{'name': g.name, 'players': len(g.players), 'locked': g.password != ''} for g in games if not g.started and len(g.players) < 7])
@sio.event @sio.event
def connect(sid, environ): def connect(sid, environ):
@ -62,11 +63,20 @@ def create_room(sid, room_name):
advertise_lobbies() advertise_lobbies()
@sio.event @sio.event
def join_room(sid, room_name): def private(sid):
g = sio.get_session(sid).game
g.set_private()
advertise_lobbies()
@sio.event
def join_room(sid, room):
room_name = room['name']
print(f'{sid} joined a room named {room_name}') print(f'{sid} joined a room named {room_name}')
i = [g.name for g in games].index(room_name)
if games[i].password != '' and games[i].password != room['password'].upper():
return
sio.leave_room(sid, 'lobby') sio.leave_room(sid, 'lobby')
sio.enter_room(sid, room_name) sio.enter_room(sid, room_name)
i = [g.name for g in games].index(room_name)
while len([p for p in games[i].players if p.name == sio.get_session(sid).name]): while len([p for p in games[i].players if p.name == sio.get_session(sid).name]):
sio.get_session(sid).name += '_1' sio.get_session(sid).name += '_1'
games[i].add_player(sio.get_session(sid)) games[i].add_player(sio.get_session(sid))

View File

@ -2,12 +2,8 @@
from typing import List, Set, Dict, Tuple, Optional from typing import List, Set, Dict, Tuple, Optional
import random import random
import socketio import socketio
import cards
from cards import Bang
import players import players
from players import PendingAction, Player
import characters import characters
from characters import all_characters
from deck import Deck from deck import Deck
import roles import roles
@ -23,6 +19,7 @@ class Game:
self.readyCount = 0 self.readyCount = 0
self.waiting_for = 0 self.waiting_for = 0
self.initial_players = 0 self.initial_players = 0
self.password = ''
def add_player(self, player: players.Player): def add_player(self, player: players.Player):
if player in self.players or len(self.players) >= 7: if player in self.players or len(self.players) >= 7:
@ -30,16 +27,24 @@ class Game:
player.join_game(self) player.join_game(self)
self.players.append(player) self.players.append(player)
print(f'Added player {player.name} to game') print(f'Added player {player.name} to game')
self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players]}) self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players], 'password': self.password})
self.sio.emit('chat_message', room=self.name, data=f'{player.name} è entrato nella lobby.') self.sio.emit('chat_message', room=self.name, data=f'{player.name} è entrato nella lobby.')
def set_private(self):
if self.password == '':
self.password = ''.join(random.choice("AEIOUJKZT123456789") for x in range(6))
print(self.name, 'is now private pwd', self.password)
else:
self.password = ''
self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players], 'password': self.password})
def notify_character_selection(self): def notify_character_selection(self):
self.readyCount += 1 self.readyCount += 1
if self.readyCount == len(self.players): if self.readyCount == len(self.players):
self.distribute_roles() self.distribute_roles()
def choose_characters(self): def choose_characters(self):
char_cards = random.sample(all_characters(), len(self.players)*2) char_cards = random.sample(characters.all_characters(), len(self.players)*2)
for i in range(len(self.players)): for i in range(len(self.players)):
self.players[i].set_available_character(char_cards[i * 2 : i * 2 + 2]) self.players[i].set_available_character(char_cards[i * 2 : i * 2 + 2])
@ -80,7 +85,7 @@ class Game:
self.players[i].notify_self() self.players[i].notify_self()
self.play_turn() self.play_turn()
def attack_others(self, attacker:Player): def attack_others(self, attacker: players.Player):
attacker.pending_action = players.PendingAction.WAIT attacker.pending_action = players.PendingAction.WAIT
attacker.notify_self() attacker.notify_self()
self.waiting_for = 0 self.waiting_for = 0
@ -93,7 +98,7 @@ class Game:
attacker.pending_action = players.PendingAction.PLAY attacker.pending_action = players.PendingAction.PLAY
attacker.notify_self() attacker.notify_self()
def indian_others(self, attacker:Player): def indian_others(self, attacker: players.Player):
attacker.pending_action = players.PendingAction.WAIT attacker.pending_action = players.PendingAction.WAIT
attacker.notify_self() attacker.notify_self()
self.waiting_for = 0 self.waiting_for = 0
@ -106,14 +111,14 @@ class Game:
attacker.pending_action = players.PendingAction.PLAY attacker.pending_action = players.PendingAction.PLAY
attacker.notify_self() attacker.notify_self()
def attack(self, attacker:Player, target_username:str): def attack(self, attacker: players.Player, target_username:str):
if self.players[self.players_map[target_username]].get_banged(attacker=attacker, double=isinstance(attacker.character, characters.SlabTheKiller)): if self.players[self.players_map[target_username]].get_banged(attacker=attacker, double=isinstance(attacker.character, characters.SlabTheKiller)):
self.readyCount = 0 self.readyCount = 0
self.waiting_for = 1 self.waiting_for = 1
attacker.pending_action = players.PendingAction.WAIT attacker.pending_action = players.PendingAction.WAIT
attacker.notify_self() attacker.notify_self()
def duel(self, attacker:Player, target_username:str): def duel(self, attacker: players.Player, target_username:str):
if self.players[self.players_map[target_username]].get_dueled(attacker=attacker): if self.players[self.players_map[target_username]].get_dueled(attacker=attacker):
self.readyCount = 0 self.readyCount = 0
self.waiting_for = 1 self.waiting_for = 1
@ -230,7 +235,7 @@ class Game:
if died_in_his_turn: if died_in_his_turn:
self.next_turn() self.next_turn()
def get_visible_players(self, player:Player): def get_visible_players(self, player: players.Player):
i = self.players.index(player) i = self.players.index(player)
sight = player.get_sight() sight = player.get_sight()
return [{ return [{

View File

@ -9,6 +9,7 @@
}, },
"dependencies": { "dependencies": {
"core-js": "^3.6.5", "core-js": "^3.6.5",
"pretty-checkbox-vue": "^1.1.9",
"socket.io-client": "^3.0.3", "socket.io-client": "^3.0.3",
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-socket.io": "^3.0.10" "vue-socket.io": "^3.0.10"

View File

@ -5,7 +5,6 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
<script src="https://twemoji.maxcdn.com/v/latest/twemoji.min.js" crossorigin="anonymous"></script>
<title><%= htmlWebpackPlugin.options.title %></title> <title><%= htmlWebpackPlugin.options.title %></title>
</head> </head>
<body> <body>

View File

@ -109,7 +109,7 @@ export default {
return { return {
name: lobby.name, name: lobby.name,
icon: "💥", icon: "💥",
number: `${lobby.players}🤠`, number: `${lobby.players}🤠 ${lobby.locked?'🔐':''}`,
is_equipment: true, is_equipment: true,
} }
}, },
@ -120,7 +120,8 @@ export default {
e.preventDefault(); e.preventDefault();
}, },
joinLobby(lobby) { joinLobby(lobby) {
this.$socket.emit('join_room', lobby.name) let password = lobby.locked ? prompt("Room password:", "") : '';
this.$socket.emit('join_room', {name:lobby.name,password:password})
}, },
init() { init() {
location.reload(); location.reload();
@ -134,6 +135,7 @@ export default {
</script> </script>
<style> <style>
@import '../node_modules/pretty-checkbox/dist/pretty-checkbox.css';
#app { #app {
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;

View File

@ -3,6 +3,10 @@
<div style="flex-grow: 4;"> <div style="flex-grow: 4;">
<h2 v-if="!started">Lobby: {{ lobbyName }}</h2> <h2 v-if="!started">Lobby: {{ lobbyName }}</h2>
<h3>Giocatori (tu sei {{username}})</h3> <h3>Giocatori (tu sei {{username}})</h3>
<h3 v-if="!started && password !== ''">Password: {{ password }}</h3>
<div v-if="!started && isRoomOwner">
<PrettyCheck class="p-switch p-fill" v-model="privateRoom">Stanza Privata</PrettyCheck>
</div>
<div class="players-table"> <div class="players-table">
<Card v-if="startGameCard" :card="startGameCard" @click.native="startGame"/> <Card v-if="startGameCard" :card="startGameCard" @click.native="startGame"/>
<!-- <div style="position: relative;width:260pt;height:400pt;"> --> <!-- <div style="position: relative;width:260pt;height:400pt;"> -->
@ -37,6 +41,7 @@
</template> </template>
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'
import Card from '@/components/Card.vue' import Card from '@/components/Card.vue'
import Chooser from './Chooser.vue' import Chooser from './Chooser.vue'
import Chat from './Chat.vue' import Chat from './Chat.vue'
@ -53,6 +58,7 @@ export default {
Player, Player,
Deck, Deck,
TinyHand, TinyHand,
PrettyCheck,
}, },
props: { props: {
username: String username: String
@ -69,11 +75,14 @@ export default {
chooseCards: [], chooseCards: [],
wantsToEndTurn: false, wantsToEndTurn: false,
selectedInfo: null, selectedInfo: null,
privateRoom: false,
password: '',
}), }),
sockets: { sockets: {
room(data) { room(data) {
this.lobbyName = data.name this.lobbyName = data.name
this.started = data.started this.started = data.started
this.password = data.password
this.players = data.players.map(x => { this.players = data.players.map(x => {
return { return {
name: x, name: x,
@ -98,8 +107,11 @@ export default {
// }, // },
}, },
computed: { computed: {
isRoomOwner() {
return this.players[0].name == this.username
},
startGameCard() { startGameCard() {
if (!this.started && this.players.length > 2 && this.players[0].name == this.username) { if (!this.started && this.players.length > 2 && this.isRoomOwner) {
return { return {
name: 'Start', name: 'Start',
icon: '▶️', icon: '▶️',
@ -179,6 +191,11 @@ export default {
this.$socket.emit('draw', name) this.$socket.emit('draw', name)
}, },
}, },
watch: {
privateRoom() {
this.$socket.emit('private')
}
}
} }
</script> </script>

View File

@ -8,6 +8,9 @@ Vue.use(new VueSocketIO({
connection: Vue.config.devtools ? 'http://localhost:5001' : window.location.origin, connection: Vue.config.devtools ? 'http://localhost:5001' : window.location.origin,
})) }))
import PrettyCheckbox from 'pretty-checkbox-vue';
Vue.use(PrettyCheckbox)
new Vue({ new Vue({
render: h => h(App), render: h => h(App),
}).$mount('#app') }).$mount('#app')

View File

@ -6651,6 +6651,18 @@ prettier@^1.18.2:
resolved "https://registry.npm.taobao.org/prettier/download/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" resolved "https://registry.npm.taobao.org/prettier/download/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha1-99f1/4qc2HKnvkyhQglZVqYHl8s= integrity sha1-99f1/4qc2HKnvkyhQglZVqYHl8s=
pretty-checkbox-vue@^1.1.9:
version "1.1.9"
resolved "https://registry.yarnpkg.com/pretty-checkbox-vue/-/pretty-checkbox-vue-1.1.9.tgz#2d4bfc7f20c54a0e7b94b3d205641dbf8f390fb4"
integrity sha512-45HOanzF+BUTD5prwCoNrtEFYVzWtASTIIPtPQxGCajC097pFD/9mbyjEjoTsu8Tk4/rSyA7RNk6JpFWVHpLag==
dependencies:
pretty-checkbox "^3.0.3"
pretty-checkbox@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/pretty-checkbox/-/pretty-checkbox-3.0.3.tgz#d49c8013a8fc08ee0c2d6ebde453464bfdbc428e"
integrity sha1-1JyAE6j8CO4MLW695FNGS/28Qo4=
pretty-error@^2.0.2: pretty-error@^2.0.2:
version "2.1.2" version "2.1.2"
resolved "https://registry.npm.taobao.org/pretty-error/download/pretty-error-2.1.2.tgz?cache=0&sync_timestamp=1603050722482&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpretty-error%2Fdownload%2Fpretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" resolved "https://registry.npm.taobao.org/pretty-error/download/pretty-error-2.1.2.tgz?cache=0&sync_timestamp=1603050722482&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpretty-error%2Fdownload%2Fpretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6"