Add game history.
This commit is contained in:
parent
91523a80a1
commit
7bdab36739
@ -187,6 +187,12 @@ impl App {
|
|||||||
)).await.ok();
|
)).await.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRPacketData::RGameHistory(response) => {
|
||||||
|
socket.send(Message::Binary(
|
||||||
|
encode_response(CODE_GAME_HISTORY, response.encode())
|
||||||
|
)).await.ok();
|
||||||
|
}
|
||||||
|
|
||||||
_ => { }
|
_ => { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +463,7 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
|||||||
if let Some(session) = app.sessions.get(&request.token) {
|
if let Some(session) = app.sessions.get(&request.token) {
|
||||||
// Send GameState update to all connections.
|
// Send GameState update to all connections.
|
||||||
let mut packets = Vec::new();
|
let mut packets = Vec::new();
|
||||||
let game_state = generate_gamestate(&app, session);
|
let game_state = generate_game_state(&app, session);
|
||||||
|
|
||||||
for (cid, player) in session.get_connections() {
|
for (cid, player) in session.get_connections() {
|
||||||
if cid != qr.id {
|
if cid != qr.id {
|
||||||
@ -546,7 +546,8 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
|||||||
println!("Request: Game State");
|
println!("Request: Game State");
|
||||||
|
|
||||||
if let Some(session) = app.sessions.get(&request.token) {
|
if let Some(session) = app.sessions.get(&request.token) {
|
||||||
response = generate_gamestate(&app, &session);
|
response.status = STATUS_OK;
|
||||||
|
response = generate_game_state(&app, &session);
|
||||||
|
|
||||||
if user_id.is_some() {
|
if user_id.is_some() {
|
||||||
if user_id == session.p_dawn.user { response.player = 0; }
|
if user_id == session.p_dawn.user { response.player = 0; }
|
||||||
@ -610,6 +611,21 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRPacketData::QGameHistory(request) => {
|
||||||
|
let mut response = PacketGameHistoryResponse::new();
|
||||||
|
|
||||||
|
println!("Request: Game History");
|
||||||
|
|
||||||
|
if let Some(session) = app.sessions.get(&request.token) {
|
||||||
|
response.status = STATUS_OK;
|
||||||
|
response = generate_game_history(&app, &session);
|
||||||
|
} else {
|
||||||
|
response.status = STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(QRPacket::new(qr.id, QRPacketData::RGameHistory(response)))
|
||||||
|
}
|
||||||
|
|
||||||
_ => { Some(QRPacket::new(0, QRPacketData::None)) }
|
_ => { Some(QRPacket::new(0, QRPacketData::None)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -619,7 +635,7 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_gamestate(app:&App, session:&Session) -> protocol::PacketGameStateResponse
|
fn generate_game_state(app:&App, session:&Session) -> protocol::PacketGameStateResponse
|
||||||
{
|
{
|
||||||
use protocol::{PacketGameStateResponse, PacketGameStateResponsePiece};
|
use protocol::{PacketGameStateResponse, PacketGameStateResponsePiece};
|
||||||
|
|
||||||
@ -666,3 +682,28 @@ fn generate_gamestate(app:&App, session:&Session) -> protocol::PacketGameStateRe
|
|||||||
|
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_game_history(app:&App, session:&Session) -> protocol::PacketGameHistoryResponse
|
||||||
|
{
|
||||||
|
use protocol::PacketGameHistoryResponse;
|
||||||
|
|
||||||
|
let mut response = PacketGameHistoryResponse::new();
|
||||||
|
|
||||||
|
// Get Dawn handle
|
||||||
|
if let Some(id) = session.p_dawn.user {
|
||||||
|
if let Some(user) = app.get_user_by_id(id) {
|
||||||
|
response.dawn_handle = user.handle.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Dusk handle
|
||||||
|
if let Some(id) = session.p_dusk.user {
|
||||||
|
if let Some(user) = app.get_user_by_id(id) {
|
||||||
|
response.dusk_handle = user.handle.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response.history = session.game.history.clone();
|
||||||
|
|
||||||
|
response
|
||||||
|
}
|
||||||
|
@ -161,6 +161,16 @@ pub async fn handle_ws(ws:WebSocketStream<TokioIo<Upgraded>>, args:HttpServiceAr
|
|||||||
Err(_) => { println!("error: packet decode failed."); }
|
Err(_) => { println!("error: packet decode failed."); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CODE_GAME_HISTORY => match PacketGameHistory::decode(&data, &mut index) {
|
||||||
|
Ok(packet) => {
|
||||||
|
args.bus.send(
|
||||||
|
bus_ds,
|
||||||
|
QRPacket::new(conn_id, QRPacketData::QGameHistory(packet))
|
||||||
|
).ok();
|
||||||
|
}
|
||||||
|
Err(_) => { println!("error: packet decode failed."); }
|
||||||
|
}
|
||||||
|
|
||||||
_ => { }
|
_ => { }
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
@ -31,3 +31,4 @@ pub const CODE_SESSION_LEAVE :u16 = 0x002F;
|
|||||||
|
|
||||||
pub const CODE_GAME_STATE :u16 = 0x0030;
|
pub const CODE_GAME_STATE :u16 = 0x0030;
|
||||||
pub const CODE_GAME_PLAY :u16 = 0x0031;
|
pub const CODE_GAME_PLAY :u16 = 0x0031;
|
||||||
|
pub const CODE_GAME_HISTORY :u16 = 0x0032;
|
||||||
|
@ -40,6 +40,9 @@ pub enum QRPacketData {
|
|||||||
RGameState(PacketGameStateResponse),
|
RGameState(PacketGameStateResponse),
|
||||||
|
|
||||||
QGamePlay(PacketGamePlay),
|
QGamePlay(PacketGamePlay),
|
||||||
|
|
||||||
|
QGameHistory(PacketGameHistory),
|
||||||
|
RGameHistory(PacketGameHistoryResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
83
server/src/protocol/packet/game_history.rs
Normal file
83
server/src/protocol/packet/game_history.rs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
use crate::{
|
||||||
|
app::session::SessionToken,
|
||||||
|
util::pack::pack_u16,
|
||||||
|
};
|
||||||
|
|
||||||
|
use game::history::Play;
|
||||||
|
|
||||||
|
use super::Packet;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct PacketGameHistory {
|
||||||
|
pub token:SessionToken,
|
||||||
|
}
|
||||||
|
impl PacketGameHistory {
|
||||||
|
pub fn new() -> Self
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
token:SessionToken::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Packet for PacketGameHistory {
|
||||||
|
type Data = Self;
|
||||||
|
|
||||||
|
fn decode(data:&Vec<u8>, index:&mut usize) -> Result<Self::Data, ()>
|
||||||
|
{
|
||||||
|
let mut result = Self::new();
|
||||||
|
|
||||||
|
if data.len() - *index == 8 {
|
||||||
|
for i in 0..8 {
|
||||||
|
result.token[i] = data[*index];
|
||||||
|
*index += 1;
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct PacketGameHistoryResponse {
|
||||||
|
pub status:u16,
|
||||||
|
pub dawn_handle:String,
|
||||||
|
pub dusk_handle:String,
|
||||||
|
pub history:Vec<Play>,
|
||||||
|
}
|
||||||
|
impl PacketGameHistoryResponse {
|
||||||
|
pub fn new() -> Self
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
status:0,
|
||||||
|
dawn_handle:String::new(),
|
||||||
|
dusk_handle:String::new(),
|
||||||
|
history:Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Packet for PacketGameHistoryResponse {
|
||||||
|
type Data = Self;
|
||||||
|
|
||||||
|
fn encode(&self) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let mut history_bytes = Vec::new();
|
||||||
|
for play in &self.history {
|
||||||
|
let mut data = 0;
|
||||||
|
data |= play.source as u16;
|
||||||
|
data |= (play.from as u16) << 4;
|
||||||
|
data |= (play.to as u16) << 10;
|
||||||
|
history_bytes.append(&mut pack_u16(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
[
|
||||||
|
pack_u16(self.status),
|
||||||
|
pack_u16(self.dawn_handle.len() as u16),
|
||||||
|
self.dawn_handle.as_bytes().to_vec(),
|
||||||
|
pack_u16(self.dusk_handle.len() as u16),
|
||||||
|
self.dusk_handle.as_bytes().to_vec(),
|
||||||
|
pack_u16(self.history.len() as u16),
|
||||||
|
history_bytes,
|
||||||
|
].concat()
|
||||||
|
}
|
||||||
|
}
|
@ -98,8 +98,8 @@ impl Packet for PacketGameStateResponse {
|
|||||||
|
|
||||||
let mut play = 0;
|
let mut play = 0;
|
||||||
play |= self.play.source as u16;
|
play |= self.play.source as u16;
|
||||||
play |= (self.play.from as u16) << 1;
|
play |= (self.play.from as u16) << 4;
|
||||||
play |= (self.play.to as u16) << 7;
|
play |= (self.play.to as u16) << 10;
|
||||||
|
|
||||||
let mut piece_bytes = Vec::new();
|
let mut piece_bytes = Vec::new();
|
||||||
for piece in &self.pieces {
|
for piece in &self.pieces {
|
||||||
|
@ -11,6 +11,7 @@ mod session_retire; pub use session_retire::*;
|
|||||||
|
|
||||||
mod game_state; pub use game_state::*;
|
mod game_state; pub use game_state::*;
|
||||||
mod game_play; pub use game_play::*;
|
mod game_play; pub use game_play::*;
|
||||||
|
mod game_history; pub use game_history::*;
|
||||||
|
|
||||||
mod prelude {
|
mod prelude {
|
||||||
pub trait Packet {
|
pub trait Packet {
|
||||||
|
@ -35,6 +35,7 @@ const OpCode = {
|
|||||||
|
|
||||||
GameState :0x0030,
|
GameState :0x0030,
|
||||||
GamePlay :0x0031,
|
GamePlay :0x0031,
|
||||||
|
GameHistory :0x0032,
|
||||||
};
|
};
|
||||||
|
|
||||||
const GameState = {
|
const GameState = {
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
let INTERFACE_DATA = null;
|
let INTERFACE_DATA = null;
|
||||||
|
|
||||||
const INTERFACE = {
|
const INTERFACE = {
|
||||||
|
Mode: {
|
||||||
|
Local: 0,
|
||||||
|
Online: 1,
|
||||||
|
Replay: 2,
|
||||||
|
},
|
||||||
|
|
||||||
Color: {
|
Color: {
|
||||||
Background: "#101010",
|
Background: "#101010",
|
||||||
Text: "#c0c0c0",
|
Text: "#c0c0c0",
|
||||||
@ -196,18 +202,10 @@ const INTERFACE = {
|
|||||||
if(is_valid) {
|
if(is_valid) {
|
||||||
|
|
||||||
// Send message to server for online game.
|
// Send message to server for online game.
|
||||||
if(INTERFACE_DATA.online) {
|
switch(INTERFACE_DATA.mode) {
|
||||||
let move_data = INTERFACE_DATA.select.source | (INTERFACE_DATA.select.tile << 1) | (INTERFACE_DATA.hover.tile << 7);
|
|
||||||
MESSAGE_COMPOSE([
|
|
||||||
PACK.u16(OpCode.GamePlay),
|
|
||||||
PACK.u16(0),
|
|
||||||
PACK.u16(GAME_DATA.turn),
|
|
||||||
PACK.u16(move_data),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply action and change turn for offline game.
|
// Apply action and change turn for local game.
|
||||||
else {
|
case INTERFACE.Mode.Local: {
|
||||||
let play = new GAME.Play(INTERFACE_DATA.select.source, INTERFACE_DATA.select.tile, INTERFACE_DATA.hover.tile);
|
let play = new GAME.Play(INTERFACE_DATA.select.source, INTERFACE_DATA.select.tile, INTERFACE_DATA.hover.tile);
|
||||||
INTERFACE_DATA.play = play;
|
INTERFACE_DATA.play = play;
|
||||||
GAME_DATA.process(play);
|
GAME_DATA.process(play);
|
||||||
@ -216,7 +214,25 @@ const INTERFACE = {
|
|||||||
INTERFACE_DATA.rotate = +(!INTERFACE_DATA.rotate);
|
INTERFACE_DATA.rotate = +(!INTERFACE_DATA.rotate);
|
||||||
|
|
||||||
INTERFACE.draw();
|
INTERFACE.draw();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
// Send action to server for validation.
|
||||||
|
case INTERFACE.Mode.Online: {
|
||||||
|
let move_data = INTERFACE_DATA.select.source | (INTERFACE_DATA.select.tile << 1) | (INTERFACE_DATA.hover.tile << 7);
|
||||||
|
MESSAGE_COMPOSE([
|
||||||
|
PACK.u16(OpCode.GamePlay),
|
||||||
|
PACK.u16(0),
|
||||||
|
PACK.u16(GAME_DATA.turn),
|
||||||
|
PACK.u16(move_data),
|
||||||
|
]);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
// Branch into local game from here.
|
||||||
|
case INTERFACE.Mode.Replay: {
|
||||||
|
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERFACE_DATA.select = null;
|
INTERFACE_DATA.select = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,6 +304,10 @@ const INTERFACE = {
|
|||||||
draw() {
|
draw() {
|
||||||
if(INTERFACE_DATA === null) return;
|
if(INTERFACE_DATA === null) return;
|
||||||
|
|
||||||
|
if(INTERFACE_DATA.mode == INTERFACE.Mode.Replay) {
|
||||||
|
document.getElementById("ind_turn").innerText = INTERFACE_DATA.replay_turn + " of " + INTERFACE_DATA.history.length;
|
||||||
|
}
|
||||||
|
|
||||||
let canvas = INTERFACE_DATA.canvas;
|
let canvas = INTERFACE_DATA.canvas;
|
||||||
let ctx = INTERFACE_DATA.context;
|
let ctx = INTERFACE_DATA.context;
|
||||||
|
|
||||||
@ -363,7 +383,7 @@ const INTERFACE = {
|
|||||||
case 1: ctx.fillStyle = INTERFACE.Color.TileLight; break;
|
case 1: ctx.fillStyle = INTERFACE.Color.TileLight; break;
|
||||||
case 2: ctx.fillStyle = INTERFACE.Color.TileDark; break;
|
case 2: ctx.fillStyle = INTERFACE.Color.TileDark; break;
|
||||||
}
|
}
|
||||||
if(GAME_DATA.turn > 0 && (INTERFACE_DATA.play.to == i || (INTERFACE_DATA.play.source == 0 && INTERFACE_DATA.play.from == i))) {
|
if(GAME_DATA.turn > 0 && INTERFACE_DATA.play.source < 2 && (INTERFACE_DATA.play.to == i || (INTERFACE_DATA.play.source == 0 && INTERFACE_DATA.play.from == i))) {
|
||||||
ctx.fillStyle = INTERFACE.Color.HintPlay;
|
ctx.fillStyle = INTERFACE.Color.HintPlay;
|
||||||
} else if(GAME_DATA.state.check && piece !== null && piece.piece == GAME.Const.PieceId.Omen && piece.player == (GAME_DATA.turn & 1)) {
|
} else if(GAME_DATA.state.check && piece !== null && piece.piece == GAME.Const.PieceId.Omen && piece.player == (GAME_DATA.turn & 1)) {
|
||||||
ctx.fillStyle = INTERFACE.Color.HintCheck;
|
ctx.fillStyle = INTERFACE.Color.HintCheck;
|
||||||
@ -691,18 +711,28 @@ const INTERFACE = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
init(data, online) {
|
init(data, mode) {
|
||||||
GAME.init();
|
GAME.init();
|
||||||
|
|
||||||
let token = null;
|
let token = null;
|
||||||
let player = 0;
|
let player = 0;
|
||||||
|
let history = [ ];
|
||||||
if(data !== null) {
|
if(data !== null) {
|
||||||
|
switch(mode) {
|
||||||
|
case INTERFACE.Mode.Online: {
|
||||||
token = data.token;
|
token = data.token;
|
||||||
player = data.mode;
|
player = data.mode;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case INTERFACE.Mode.Replay: {
|
||||||
|
history = data.history;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERFACE_DATA = {
|
INTERFACE_DATA = {
|
||||||
online: online,
|
mode: mode,
|
||||||
|
|
||||||
token: token,
|
token: token,
|
||||||
|
|
||||||
@ -721,6 +751,9 @@ const INTERFACE = {
|
|||||||
play: null,
|
play: null,
|
||||||
retire:false,
|
retire:false,
|
||||||
|
|
||||||
|
replay_turn: 0,
|
||||||
|
history: history,
|
||||||
|
|
||||||
Ui: {
|
Ui: {
|
||||||
scale: 0,
|
scale: 0,
|
||||||
margin: 0,
|
margin: 0,
|
||||||
@ -742,20 +775,25 @@ const INTERFACE = {
|
|||||||
canvas.addEventListener("mousedown", INTERFACE.click);
|
canvas.addEventListener("mousedown", INTERFACE.click);
|
||||||
window.addEventListener("resize", INTERFACE.draw);
|
window.addEventListener("resize", INTERFACE.draw);
|
||||||
|
|
||||||
if(INTERFACE_DATA.online) {
|
switch(INTERFACE_DATA.mode) {
|
||||||
|
case INTERFACE.Mode.Replay:
|
||||||
|
case INTERFACE.Mode.Local: {
|
||||||
|
INTERFACE.draw();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case INTERFACE.Mode.Online: {
|
||||||
MESSAGE_COMPOSE([
|
MESSAGE_COMPOSE([
|
||||||
PACK.u16(OpCode.GameState),
|
PACK.u16(OpCode.GameState),
|
||||||
INTERFACE_DATA.token,
|
INTERFACE_DATA.token,
|
||||||
]);
|
]);
|
||||||
} else {
|
} break;
|
||||||
INTERFACE.draw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
uninit() {
|
uninit() {
|
||||||
if(INTERFACE_DATA !== null) {
|
if(INTERFACE_DATA !== null) {
|
||||||
if(INTERFACE_DATA.online) {
|
if(INTERFACE_DATA.mode == INTERFACE.Mode.Online) {
|
||||||
MESSAGE_COMPOSE([
|
MESSAGE_COMPOSE([
|
||||||
PACK.u16(OpCode.SessionLeave),
|
PACK.u16(OpCode.SessionLeave),
|
||||||
]);
|
]);
|
||||||
@ -833,13 +871,44 @@ const INTERFACE = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
retire() {
|
retire() {
|
||||||
if(INTERFACE_DATA.online) {
|
if(INTERFACE_DATA.mode == INTERFACE.Mode.Online) {
|
||||||
MESSAGE_COMPOSE([
|
MESSAGE_COMPOSE([
|
||||||
PACK.u16(OpCode.SessionRetire),
|
PACK.u16(OpCode.SessionRetire),
|
||||||
INTERFACE_DATA.token,
|
INTERFACE_DATA.token,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
replay_prev() {
|
||||||
|
if(INTERFACE_DATA.mode == INTERFACE.Mode.Replay) {
|
||||||
|
if(INTERFACE_DATA.replay_turn > 0) {
|
||||||
|
INTERFACE_DATA.replay_turn--;
|
||||||
|
|
||||||
|
GAME.init();
|
||||||
|
for(let i = 0; i < INTERFACE_DATA.replay_turn; ++i) {
|
||||||
|
GAME_DATA.process(INTERFACE_DATA.history[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERFACE_DATA.play = null;
|
||||||
|
if(INTERFACE_DATA.replay_turn > 0) {
|
||||||
|
INTERFACE_DATA.play = INTERFACE_DATA.history[INTERFACE_DATA.replay_turn - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERFACE.draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
replay_next() {
|
||||||
|
if(INTERFACE_DATA.mode == INTERFACE.Mode.Replay) {
|
||||||
|
if(INTERFACE_DATA.replay_turn < INTERFACE_DATA.history.length) {
|
||||||
|
GAME_DATA.process(INTERFACE_DATA.history[INTERFACE_DATA.replay_turn]);
|
||||||
|
INTERFACE_DATA.play = INTERFACE_DATA.history[INTERFACE_DATA.replay_turn];
|
||||||
|
INTERFACE_DATA.replay_turn++;
|
||||||
|
INTERFACE.draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
INTERFACE.Radius = 2.0 / Math.sqrt(3.0);
|
INTERFACE.Radius = 2.0 / Math.sqrt(3.0);
|
||||||
|
@ -464,13 +464,12 @@ const SCENES = {
|
|||||||
UI.clear(table);
|
UI.clear(table);
|
||||||
|
|
||||||
if(data !== null) {
|
if(data !== null) {
|
||||||
table.appendChild(UI.session_table(data.records));
|
table.appendChild(UI.session_table_history(data.records));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case OpCode.SessionCreate:
|
case OpCode.GameHistory: {
|
||||||
case OpCode.SessionJoin: {
|
|
||||||
if(data.status == Status.Ok) {
|
if(data.status == Status.Ok) {
|
||||||
LOAD(SCENES.Game, data);
|
LOAD(SCENES.GameHistory, data);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -525,7 +524,7 @@ const SCENES = {
|
|||||||
canvas.setAttribute("id", "game");
|
canvas.setAttribute("id", "game");
|
||||||
MAIN.appendChild(canvas);
|
MAIN.appendChild(canvas);
|
||||||
|
|
||||||
INTERFACE.init(data, true);
|
INTERFACE.init(data, INTERFACE.Mode.Online);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@ -566,7 +565,51 @@ const SCENES = {
|
|||||||
canvas.setAttribute("id", "game");
|
canvas.setAttribute("id", "game");
|
||||||
MAIN.appendChild(canvas);
|
MAIN.appendChild(canvas);
|
||||||
|
|
||||||
INTERFACE.init(data, false);
|
INTERFACE.init(data, INTERFACE.Mode.Local);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
unload() {
|
||||||
|
INTERFACE.uninit();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
GameHistory:{
|
||||||
|
load(data) {
|
||||||
|
let buttons_bottom = [ ];
|
||||||
|
buttons_bottom.push(UI.button("Back", () => { LOAD(SCENES.Browse) }));
|
||||||
|
|
||||||
|
UI.nav([
|
||||||
|
UI.button("Rotate", () => { INTERFACE.rotate(); }),
|
||||||
|
UI.button("Mirror", () => { INTERFACE.mirror(); }),
|
||||||
|
], buttons_bottom);
|
||||||
|
|
||||||
|
|
||||||
|
let left_buttons = [ ];
|
||||||
|
if(CONTEXT.Auth !== null) {
|
||||||
|
left_buttons.push(UI.button("Start", () => {
|
||||||
|
MESSAGE_SESSION_START();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
let ind_turn = UI.div([UI.text("0 of 0")]);
|
||||||
|
ind_turn.setAttribute("id", "ind_turn");
|
||||||
|
|
||||||
|
UI.mainnav(
|
||||||
|
left_buttons,
|
||||||
|
[
|
||||||
|
ind_turn,
|
||||||
|
UI.button("◀", () => { INTERFACE.replay_prev(); }),
|
||||||
|
UI.button("▶", () => { INTERFACE.replay_next(); }),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
let canvas = document.createElement("canvas");
|
||||||
|
canvas.setAttribute("id", "game");
|
||||||
|
MAIN.appendChild(canvas);
|
||||||
|
|
||||||
|
INTERFACE.init(data, INTERFACE.Mode.Replay);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -319,6 +319,47 @@ function MESSAGE(event) {
|
|||||||
data.play.to = (result.data >> 10) & 0x3F;
|
data.play.to = (result.data >> 10) & 0x3F;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case OpCode.GameHistory: {
|
||||||
|
console.log("RECV GameHistory");
|
||||||
|
|
||||||
|
data = {
|
||||||
|
status:0,
|
||||||
|
dawn:"",
|
||||||
|
dusk:"",
|
||||||
|
history:[ ],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Status
|
||||||
|
result = UNPACK.u16(bytes, index);
|
||||||
|
index = result.index;
|
||||||
|
data.status = result.data;
|
||||||
|
|
||||||
|
// Handles
|
||||||
|
result = UNPACK.string(bytes, index);
|
||||||
|
index = result.index;
|
||||||
|
data.dawn = result.data;
|
||||||
|
|
||||||
|
result = UNPACK.string(bytes, index);
|
||||||
|
index = result.index;
|
||||||
|
data.dusk = result.data;
|
||||||
|
|
||||||
|
// Pieces
|
||||||
|
result = UNPACK.u16(bytes, index);
|
||||||
|
index = result.index;
|
||||||
|
let history_length = result.data;
|
||||||
|
|
||||||
|
for(let i = 0; i < history_length; ++i) {
|
||||||
|
result = UNPACK.u16(bytes, index);
|
||||||
|
index = result.index;
|
||||||
|
|
||||||
|
data.history.push(new GAME.Play(
|
||||||
|
result.data & 0xF,
|
||||||
|
(result.data >> 4) & 0x3F,
|
||||||
|
(result.data >> 10) & 0x3F,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.log("RECV Undefined " + code);
|
console.log("RECV Undefined " + code);
|
||||||
return;
|
return;
|
||||||
|
37
www/js/ui.js
37
www/js/ui.js
@ -219,6 +219,43 @@ const UI = {
|
|||||||
return tbody;
|
return tbody;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
session_table_history(records) {
|
||||||
|
let rows = [ ];
|
||||||
|
|
||||||
|
for(let r = 0; r < records.length; ++r) {
|
||||||
|
let buttons = [ ];
|
||||||
|
let view_callback = function() {
|
||||||
|
MESSAGE_COMPOSE([
|
||||||
|
PACK.u16(OpCode.GameHistory),
|
||||||
|
this.token,
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
view_callback = view_callback.bind({token: records[r].token});
|
||||||
|
|
||||||
|
buttons.push(UI.button("View", view_callback));
|
||||||
|
|
||||||
|
let dawn = UI.text(records[r].dawn);
|
||||||
|
if(records[r].dawn == "") { dawn = UI.span([UI.text("Vacant")], "text-system"); }
|
||||||
|
|
||||||
|
let dusk = UI.text(records[r].dusk);
|
||||||
|
if(records[r].dusk == "") { dusk = UI.span([UI.text("Vacant")], "text-system"); }
|
||||||
|
|
||||||
|
rows.push([
|
||||||
|
dawn,
|
||||||
|
dusk,
|
||||||
|
UI.text(records[r].turn),
|
||||||
|
buttons,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let tbody = UI.table_content(
|
||||||
|
[ "Dawn", "Dusk", "Turn", "" ],
|
||||||
|
rows,
|
||||||
|
);
|
||||||
|
|
||||||
|
return tbody;
|
||||||
|
},
|
||||||
|
|
||||||
clear(dom) {
|
clear(dom) {
|
||||||
while(dom.lastChild !== null) { dom.removeChild(document.body.lastChild); }
|
while(dom.lastChild !== null) { dom.removeChild(document.body.lastChild); }
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user