Skip to content

Commit

Permalink
Add room owner's command to set players' status
Browse files Browse the repository at this point in the history
  • Loading branch information
rnixik committed Jan 28, 2018
1 parent ece6625 commit 4d30ca3
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 29 deletions.
6 changes: 3 additions & 3 deletions client.go
Expand Up @@ -53,9 +53,9 @@ type Client struct {

// ClientCommand is a command message from connected client.
type ClientCommand struct {
Type string `json:"type"`
SubType string `json:"sub_type"`
Data interface{} `json:"data"`
Type string `json:"type"`
SubType string `json:"sub_type"`
Data json.RawMessage `json:"data"`
client *Client
}

Expand Down
13 changes: 13 additions & 0 deletions events_room.go
Expand Up @@ -4,6 +4,7 @@ type RoomMemberInfo struct {
Id uint64 `json:"id"`
Nickname string `json:"nickname"`
WantToPlay bool `json:"want_to_play"`
IsPlayer bool `json:"is_player"`
}

// RoomInfo contains info about room where client is.
Expand All @@ -13,6 +14,7 @@ type RoomInfo struct {
Name string `json:"name"`
GameStatus string `json:"game_status"`
Members []*RoomMemberInfo `json:"members"`
MaxPlayers int `json:"max_players"`
}

// RoomJoinedEvent contains info about room where client is
Expand All @@ -29,3 +31,14 @@ type RoomUpdatedEvent struct {
type RoomMemberChangedStatusEvent struct {
Room *RoomMemberInfo `json:"member"`
}

// RoomMemberChangedPlayerStatusEvent contains info about room member when his player status was changed by room owner
type RoomMemberChangedPlayerStatusEvent struct {
Room *RoomMemberInfo `json:"member"`
}

// RoomSetPlayerStatusCommandData represents data from room owner to set or unset player status of a member
type RoomSetPlayerStatusCommandData struct {
MemberId uint64 `json:"member_id"`
Status bool `json:"status"`
}
4 changes: 4 additions & 0 deletions html/css/index.css
Expand Up @@ -35,3 +35,7 @@ body {
.member-want-to-play {
color: green;
}

.member-is-player {
font-weight: bold;
}
6 changes: 5 additions & 1 deletion html/index.html
Expand Up @@ -59,8 +59,12 @@ <h2 style="text-align: center; font-size: 20px; font-weight: bold; color: #333;
<div v-if="room && room.id">
<h2>Room - {{ room.name }}</h2>
<transition-group name="slide-fade" tag="ol">
<li v-for="member in room.members" v-bind:key="member.id" v-bind:class="{ 'member-want-to-play': member.want_to_play }">
<li v-for="member in room.members" v-bind:key="member.id" v-bind:class="{ 'member-want-to-play': member.want_to_play, 'member-is-player': member.is_player }">
{{ member.nickname }}
<span v-if="room.owner_id == clientsInfo.yourId">
<button v-if="member.want_to_play && !member.is_player && playersInRoom < room.max_players" v-on:click="setPlayerStatus(member.id, true)">mark as player</button>
<button v-if="member.is_player" v-on:click="setPlayerStatus(member.id, false)">mark as spectator</button>
</span>
</li>
</transition-group>
</div>
Expand Down
53 changes: 45 additions & 8 deletions html/js/index.js
Expand Up @@ -13,7 +13,8 @@ function App() {
commandError: {},
rooms: [],
room: {},
wantToPlay: true
wantToPlay: true,
playersInRoom: 0
},
methods: {
createRoom: function (event) {
Expand All @@ -36,6 +37,9 @@ function App() {
markWantToSpectate: function () {
app.commandWantToSpectate();
this.wantToPlay = false;
},
setPlayerStatus: function (memberId, status) {
app.commandSetPlayerStatus(memberId, status);
}
}
});
Expand Down Expand Up @@ -95,10 +99,12 @@ function App() {

this.onRoomJoinedEvent = function(data) {
app.vue.room = data.room;
app.updatePlayersInRoomCounter();
}

this.onRoomUpdatedEvent = function(data) {
app.vue.room = data.room;
app.updatePlayersInRoomCounter();
}

this.onClientCommandError = function(data) {
Expand All @@ -114,17 +120,21 @@ function App() {
}

this.onRoomMemberChangedStatusEvent = function(data) {
if (!app.vue.room) {
console.warn("No room for event")
}
if (data.member.id === app.vue.clientsInfo.yourId) {
app.vue.wantToPlay = data.member.want_to_play;
}
for (let i = 0; i < app.vue.room.members.length; i++) {
if (app.vue.room.members[i].id === data.member.id) {
Vue.set(app.vue.room.members, i, data.member);
}
const memberIndex = app.getRoomMemberIndexById(data.member.id);
if (memberIndex > -1) {
Vue.set(app.vue.room.members, memberIndex, data.member);
}
}

this.onRoomMemberChangedPlayerStatusEvent = function(data) {
const memberIndex = app.getRoomMemberIndexById(data.member.id);
if (memberIndex > -1) {
Vue.set(app.vue.room.members, memberIndex, data.member);
}
app.updatePlayersInRoomCounter();
}

this.sendCommand = function(type, subType, data) {
Expand All @@ -148,6 +158,10 @@ function App() {
app.sendCommand('room', 'want_to_spectate', null);
}

this.commandSetPlayerStatus = function(memberId, status) {
app.sendCommand('room', 'set_player_status', {member_id: memberId, status: status});
}

this.getRoomIndexById = function(roomId) {
for (let i = 0; i < app.vue.rooms.length; i++) {
if (app.vue.rooms[i].id === roomId) {
Expand All @@ -156,6 +170,29 @@ function App() {
}
return -1;
}

this.getRoomMemberIndexById = function(memberId) {
if (!app.vue.room) {
console.warn("No room for event");
return -1;
}
for (let i = 0; i < app.vue.room.members.length; i++) {
if (app.vue.room.members[i].id === memberId) {
return i;
}
}
return -1;
}

this.updatePlayersInRoomCounter = function() {
let playersNum = 0;
for (let i = 0; i < app.vue.room.members.length; i++) {
if (app.vue.room.members[i].is_player) {
playersNum++;
}
}
app.vue.playersInRoom = playersNum;
}
}

(function(){
Expand Down
19 changes: 10 additions & 9 deletions lobby.go
@@ -1,9 +1,9 @@
package main

import (
"encoding/json"
"fmt"
"log"
"strconv"
"sync/atomic"
)

Expand Down Expand Up @@ -223,19 +223,20 @@ func (l *Lobby) onJoinRoomCommand(c *Client, roomId uint64) {
func (l *Lobby) onClientCommand(cc *ClientCommand) {
if cc.Type == "lobby" {
if cc.SubType == "join" {
nickname, ok := cc.Data.(string)
if ok {
l.onJoinCommand(cc.client, nickname)
//l.createNewGame(cc.client)
var nickname string
if err := json.Unmarshal(cc.Data, &nickname); err != nil {
return
}
l.onJoinCommand(cc.client, nickname)
//l.createNewGame(cc.client)
} else if cc.SubType == "create_room" {
l.onCreateNewRoomCommand(cc.client)
} else if cc.SubType == "join_room" {
roomIdStr := fmt.Sprintf("%v", cc.Data)
roomId, err := strconv.ParseUint(roomIdStr, 10, 64)
if err == nil {
l.onJoinRoomCommand(cc.client, roomId)
var roomId uint64
if err := json.Unmarshal(cc.Data, &roomId); err != nil {
return
}
l.onJoinRoomCommand(cc.client, roomId)
}
} else if cc.Type == "game" {
// demo
Expand Down
47 changes: 39 additions & 8 deletions room.go
@@ -1,16 +1,18 @@
package main

import (
"encoding/json"
"log"
)

// MaxPlayersInRoom limits maximum number of players in room
const MaxPlayersInRoom = 6
const MaxPlayersInRoom = 2

// RoomMember represents connected to a room client.
type RoomMember struct {
client ClientSender
wantToPlay bool
isPlayer bool
}

// Room represents place where some of members want to start a new game.
Expand All @@ -24,6 +26,7 @@ type Room struct {
func newRoom(roomId uint64, owner *Client) *Room {
members := make(map[*RoomMember]bool, 0)
ownerInRoom := newRoomMember(owner)
ownerInRoom.isPlayer = true
members[ownerInRoom] = true
room := &Room{roomId, ownerInRoom, members, nil}
owner.room = room
Expand All @@ -35,7 +38,7 @@ func newRoom(roomId uint64, owner *Client) *Room {
}

func newRoomMember(client ClientSender) *RoomMember {
return &RoomMember{client, true}
return &RoomMember{client, true, false}
}

// Name returns name of the room by its owner.
Expand Down Expand Up @@ -134,20 +137,46 @@ func (r *Room) changeMemberWantStatus(client *Client, wantToPlay bool) {
r.broadcastEvent(changeStatusEvent, nil)
}

func (r *Room) onWantToPlayCommand(cc *ClientCommand) {
r.changeMemberWantStatus(cc.client, true)
func (r *Room) onWantToPlayCommand(client *Client) {
r.changeMemberWantStatus(client, true)
}

func (r *Room) onWantToSpectateCommand(cc *ClientCommand) {
r.changeMemberWantStatus(cc.client, false)
func (r *Room) onWantToSpectateCommand(client *Client) {
r.changeMemberWantStatus(client, false)
r.onSetPlayerStatusCommand(client.Id(), false)
}

func (r *Room) onSetPlayerStatusCommand(memberId uint64, playerStatus bool) {
var foundMember *RoomMember
for rm := range r.members {
if rm.client.Id() == memberId {
rm.isPlayer = playerStatus
foundMember = rm
break
}
}

if foundMember == nil {
return
}

memberInfo := foundMember.memberToRoomMemberInfo()
roomMemberChangedPlayerStatusEvent := &RoomMemberChangedPlayerStatusEvent{memberInfo}
r.broadcastEvent(roomMemberChangedPlayerStatusEvent, nil)
}

func (r *Room) onClientCommand(cc *ClientCommand) {
log.Println(cc.SubType)
if cc.SubType == "want_to_play" {
r.onWantToPlayCommand(cc)
r.onWantToPlayCommand(cc.client)
} else if cc.SubType == "want_to_spectate" {
r.onWantToSpectateCommand(cc)
r.onWantToSpectateCommand(cc.client)
} else if cc.SubType == "set_player_status" {
var statusData RoomSetPlayerStatusCommandData
if err := json.Unmarshal(cc.Data, &statusData); err != nil {
return
}
r.onSetPlayerStatusCommand(statusData.MemberId, statusData.Status)
}
}

Expand All @@ -156,6 +185,7 @@ func (rm *RoomMember) memberToRoomMemberInfo() *RoomMemberInfo {
Id: rm.client.Id(),
Nickname: rm.client.Nickname(),
WantToPlay: rm.wantToPlay,
IsPlayer: rm.isPlayer,
}
}

Expand Down Expand Up @@ -192,6 +222,7 @@ func (r *Room) toRoomInfo() *RoomInfo {
Name: r.Name(),
GameStatus: gameStatus,
Members: membersInfo,
MaxPlayers: MaxPlayersInRoom,
}
return roomInfo
}

0 comments on commit 4d30ca3

Please sign in to comment.