Update joining and session lists.
This commit is contained in:
parent
0f682a21be
commit
ac3d01b0d7
@ -7,17 +7,9 @@ use crate::{
|
||||
|
||||
pub type Pool = [u8; 7];
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum GameState {
|
||||
None,
|
||||
Joinable,
|
||||
Ongoing,
|
||||
Complete,
|
||||
}
|
||||
|
||||
pub struct Game {
|
||||
pub complete:bool,
|
||||
pub turn:u16,
|
||||
pub state:GameState,
|
||||
pub board:Board,
|
||||
pub pool:[Pool; 2],
|
||||
|
||||
@ -27,7 +19,7 @@ impl Game {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
state:GameState::Joinable,
|
||||
complete:false,
|
||||
|
||||
turn:0,
|
||||
|
||||
|
@ -3,6 +3,7 @@ use game::Game;
|
||||
pub type SessionToken = [u8; 8];
|
||||
pub type SessionSecret = [u8; 8];
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Player {
|
||||
pub user:Option<u32>,
|
||||
pub connections:Vec<u32>,
|
||||
@ -23,13 +24,19 @@ pub struct Session {
|
||||
pub chain_id:usize,
|
||||
}
|
||||
impl Session {
|
||||
pub fn get_connections(&self) -> Vec<u32>
|
||||
pub fn get_connections(&self) -> Vec<(u32, u8)>
|
||||
{
|
||||
[
|
||||
self.p_dawn.connections.clone(),
|
||||
self.p_dusk.connections.clone(),
|
||||
self.connections.clone(),
|
||||
].concat()
|
||||
let mut result = Vec::new();
|
||||
for conn in &self.p_dawn.connections {
|
||||
result.push((*conn, 0));
|
||||
}
|
||||
for conn in &self.p_dusk.connections {
|
||||
result.push((*conn, 1));
|
||||
}
|
||||
for conn in &self.connections {
|
||||
result.push((*conn, 2));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn add_connection(&mut self, source:u8, id:u32)
|
||||
|
@ -261,8 +261,6 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
||||
}
|
||||
|
||||
QRPacketData::QSessionList(request) => {
|
||||
use game::game::GameState;
|
||||
|
||||
println!("Request: Session List");
|
||||
|
||||
let mut response = PacketSessionListResponse::new();
|
||||
@ -280,8 +278,12 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
||||
// - IsPlayer must have the current user in either player slot.
|
||||
// - IsLive must have both users connected to the session.
|
||||
|
||||
let mut valid = request.game_state == GameState::None || request.game_state == session.game.state;
|
||||
valid &= request.game_state != GameState::Joinable || session.p_dawn.user.is_none() || session.p_dusk.user.is_none();
|
||||
let mut valid = match request.game_state {
|
||||
1 => session.p_dawn.user.is_none() || session.p_dusk.user.is_none(),
|
||||
2 => session.p_dawn.user.is_some() && session.p_dusk.user.is_some(),
|
||||
3 => session.game.complete,
|
||||
_ => true,
|
||||
};
|
||||
valid &= !request.is_player || session.p_dawn.user == user_id || session.p_dusk.user == user_id;
|
||||
valid &= !request.is_live || (session.p_dawn.connections.len() > 0 && session.p_dusk.connections.len() > 0);
|
||||
|
||||
@ -402,14 +404,19 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
||||
// User must not already be player
|
||||
if session.p_dawn.user != user_id && session.p_dusk.user != user_id {
|
||||
|
||||
// Add user to empty player slot
|
||||
if if session.p_dawn.user.is_none() {
|
||||
session.p_dawn.user = Some(uid);
|
||||
response.mode = 0;
|
||||
true
|
||||
} else if session.p_dusk.user.is_none() {
|
||||
session.p_dusk.user = Some(uid);
|
||||
response.mode = 1;
|
||||
// Add user to session and randomize seats.
|
||||
if if session.p_dusk.user.is_none() {
|
||||
let mut r = [0u8; 1];
|
||||
rng.fill(&mut r).ok();
|
||||
if (r[0] & 1) == 0 {
|
||||
session.p_dusk = session.p_dawn.clone();
|
||||
session.p_dawn.user = Some(uid);
|
||||
session.p_dawn.connections.clear();
|
||||
response.mode = 0;
|
||||
} else {
|
||||
session.p_dusk.user = Some(uid);
|
||||
response.mode = 1;
|
||||
}
|
||||
true
|
||||
} else {
|
||||
// Session is not empty
|
||||
@ -458,12 +465,11 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
||||
let mut packets = Vec::new();
|
||||
let game_state = generate_gamestate(&app, session);
|
||||
|
||||
for cid in &session.get_connections() {
|
||||
if *cid != qr.id {
|
||||
packets.push(QRPacket::new(
|
||||
*cid,
|
||||
QRPacketData::RGameState(game_state.clone()),
|
||||
));
|
||||
for (cid, player) in session.get_connections() {
|
||||
if cid != qr.id {
|
||||
let mut gs = game_state.clone();
|
||||
gs.player = player;
|
||||
packets.push(QRPacket::new(cid, QRPacketData::RGameState(gs)));
|
||||
}
|
||||
}
|
||||
for packet in packets {
|
||||
@ -509,6 +515,11 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
||||
|
||||
if let Some(session) = app.sessions.get(&request.token) {
|
||||
response = generate_gamestate(&app, &session);
|
||||
|
||||
if user_id.is_some() {
|
||||
if user_id == session.p_dawn.user { response.player = 0; }
|
||||
else if user_id == session.p_dusk.user { response.player = 1; }
|
||||
}
|
||||
} else {
|
||||
response.status = STATUS_ERROR;
|
||||
}
|
||||
@ -540,9 +551,9 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
||||
app.filesystem.session_history_push(session.id, request.play).ok();
|
||||
|
||||
// Forward play to all clients
|
||||
for cid in &session.get_connections() {
|
||||
for (cid, _) in session.get_connections() {
|
||||
packets.push(QRPacket::new(
|
||||
*cid,
|
||||
cid,
|
||||
QRPacketData::QGamePlay(request.clone())
|
||||
));
|
||||
}
|
||||
@ -583,6 +594,8 @@ fn generate_gamestate(app:&App, session:&Session) -> protocol::PacketGameStateRe
|
||||
use protocol::{PacketGameStateResponse, PacketGameStateResponsePiece};
|
||||
|
||||
let mut response = PacketGameStateResponse::new();
|
||||
|
||||
response.player = 2;
|
||||
response.turn = session.game.turn;
|
||||
|
||||
// Get Dawn handle
|
||||
|
@ -64,6 +64,7 @@ impl PacketGameStateResponsePiece {
|
||||
pub struct PacketGameStateResponse {
|
||||
pub status:u16,
|
||||
pub turn:u16,
|
||||
pub player:u8,
|
||||
pub dawn_handle:String,
|
||||
pub dusk_handle:String,
|
||||
pub dawn_pool:Pool,
|
||||
@ -76,6 +77,7 @@ impl PacketGameStateResponse {
|
||||
Self {
|
||||
status:0,
|
||||
turn:0,
|
||||
player:0,
|
||||
dawn_handle:String::new(),
|
||||
dusk_handle:String::new(),
|
||||
dawn_pool:Pool::default(),
|
||||
@ -89,6 +91,9 @@ impl Packet for PacketGameStateResponse {
|
||||
|
||||
fn encode(&self) -> Vec<u8>
|
||||
{
|
||||
let mut flags = 0u16;
|
||||
flags |= self.player as u16;
|
||||
|
||||
let mut piece_bytes = Vec::new();
|
||||
for piece in &self.pieces {
|
||||
let piece_data: u16 = piece.valid as u16
|
||||
@ -118,6 +123,7 @@ impl Packet for PacketGameStateResponse {
|
||||
|
||||
[
|
||||
pack_u16(self.status),
|
||||
pack_u16(flags),
|
||||
pack_u16(self.turn),
|
||||
pack_u16(self.dawn_handle.len() as u16),
|
||||
self.dawn_handle.as_bytes().to_vec(),
|
||||
|
@ -2,17 +2,14 @@ use crate::{
|
||||
app::session::SessionToken,
|
||||
util::pack::{pack_u16, pack_u32, unpack_u16},
|
||||
};
|
||||
use game::{
|
||||
game::GameState,
|
||||
util::mask,
|
||||
};
|
||||
use game::util::mask;
|
||||
|
||||
use super::Packet;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PacketSessionList {
|
||||
pub page:u16,
|
||||
pub game_state:GameState,
|
||||
pub game_state:u8,
|
||||
pub is_player:bool,
|
||||
pub is_live:bool,
|
||||
}
|
||||
@ -21,7 +18,7 @@ impl PacketSessionList {
|
||||
{
|
||||
Self {
|
||||
page:0,
|
||||
game_state:GameState::Joinable,
|
||||
game_state:0,
|
||||
is_player:false,
|
||||
is_live:false,
|
||||
}
|
||||
@ -41,12 +38,7 @@ impl Packet for PacketSessionList {
|
||||
*/
|
||||
if data.len() - *index == 4 {
|
||||
let flags = unpack_u16(data, index);
|
||||
result.game_state = match flags & mask(2, 0) as u16 {
|
||||
1 => GameState::Joinable,
|
||||
2 => GameState::Ongoing,
|
||||
3 => GameState::Complete,
|
||||
_ => GameState::None,
|
||||
};
|
||||
result.game_state = (flags & mask(2, 0) as u16) as u8;
|
||||
result.is_player = (flags & mask(1, 2) as u16) != 0;
|
||||
result.is_live = (flags & mask(1, 3) as u16) != 0;
|
||||
|
||||
|
@ -717,6 +717,8 @@ const INTERFACE = {
|
||||
message(code, data) {
|
||||
switch(code) {
|
||||
case OpCode.GameState: {
|
||||
console.log(data.player);
|
||||
INTERFACE_DATA.player = data.player;
|
||||
GAME_DATA.turn = data.turn;
|
||||
|
||||
if(data.dawn.length > 0) { INTERFACE_DATA.handles[0] = data.dawn; }
|
||||
|
@ -207,7 +207,7 @@ const SCENES = {
|
||||
return true;
|
||||
},
|
||||
refresh() {
|
||||
MESSAGE_SESSION_LIST(0, 0, false, false);
|
||||
MESSAGE_SESSION_LIST(0, 2, false, false);
|
||||
},
|
||||
message(code, data) {
|
||||
switch(code) {
|
||||
@ -266,7 +266,7 @@ const SCENES = {
|
||||
return true;
|
||||
},
|
||||
refresh() {
|
||||
MESSAGE_SESSION_LIST(0, 0, true, false);
|
||||
MESSAGE_SESSION_LIST(0, 2, true, false);
|
||||
},
|
||||
message(code, data) {
|
||||
switch(code) {
|
||||
@ -334,7 +334,7 @@ const SCENES = {
|
||||
UI.clear(table);
|
||||
|
||||
if(data !== null) {
|
||||
table.appendChild(UI.session_table(data.records));
|
||||
table.appendChild(UI.session_table_join(data.records));
|
||||
}
|
||||
} break;
|
||||
case OpCode.SessionCreate:
|
||||
|
@ -205,6 +205,7 @@ function MESSAGE(event) {
|
||||
//if(bytes.length - index >= 22) {
|
||||
data = {
|
||||
status:0,
|
||||
player:2,
|
||||
turn:0,
|
||||
dawn:"",
|
||||
dusk:"",
|
||||
@ -218,6 +219,13 @@ function MESSAGE(event) {
|
||||
index = result.index;
|
||||
data.status = result.data;
|
||||
|
||||
// Flags
|
||||
result = UNPACK.u16(bytes, index);
|
||||
index = result.index;
|
||||
let flags = result.data;
|
||||
|
||||
data.player = flags & 0x3;
|
||||
|
||||
// Turn
|
||||
result = UNPACK.u16(bytes, index);
|
||||
index = result.index;
|
||||
|
33
www/js/ui.js
33
www/js/ui.js
@ -185,6 +185,39 @@ const UI = {
|
||||
return tbody;
|
||||
},
|
||||
|
||||
session_table_join(records) {
|
||||
let rows = [ ];
|
||||
|
||||
for(let r = 0; r < records.length; ++r) {
|
||||
let buttons = [ ];
|
||||
let join_callback = function() {
|
||||
MESSAGE_SESSION_JOIN(this.token, true);
|
||||
};
|
||||
join_callback = join_callback.bind({token: records[r].token});
|
||||
|
||||
if(records[r].player) {
|
||||
buttons.push(UI.button("View", join_callback));
|
||||
} else {
|
||||
buttons.push(UI.button("Join", join_callback));
|
||||
}
|
||||
|
||||
let host = UI.text(records[r].dawn);
|
||||
if(records[r].dawn == "") { dawn = UI.span([UI.text("Vacant")], "text-system"); }
|
||||
|
||||
rows.push([
|
||||
host,
|
||||
buttons,
|
||||
]);
|
||||
}
|
||||
|
||||
let tbody = UI.table_content(
|
||||
[ "Host", "" ],
|
||||
rows,
|
||||
);
|
||||
|
||||
return tbody;
|
||||
},
|
||||
|
||||
clear(dom) {
|
||||
while(dom.lastChild !== null) { dom.removeChild(document.body.lastChild); }
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user