From f3425cfac40efa445b9e3649e9930a1b507936bc Mon Sep 17 00:00:00 2001 From: yukirij Date: Thu, 17 Oct 2024 14:50:19 -0700 Subject: [PATCH] Implement profile page, UserInfo packet. --- server/src/main.rs | 2 + server/src/protocol/packet/session_list.rs | 73 ++++++++++++---------- server/src/protocol/packet/user_info.rs | 25 +++++++- www/css/profile.css | 25 ++++++++ www/css/text.css | 60 ++++++++++++++++++ www/css/ui.css | 61 ------------------ www/js/scene.js | 49 +++++++++++---- www/js/system.js | 1 - www/js/ui.js | 5 +- 9 files changed, 189 insertions(+), 112 deletions(-) create mode 100644 www/css/profile.css create mode 100644 www/css/text.css diff --git a/server/src/main.rs b/server/src/main.rs index a6f52c0..e38e78a 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -220,6 +220,8 @@ async fn main() WebCache::file("www/css/ui.css"), WebCache::file("www/css/form.css"), WebCache::file("www/css/game.css"), + WebCache::file("www/css/text.css"), + WebCache::file("www/css/profile.css"), WebCache::file("www/css/util.css"), ]).ok(); cache.cache("text/javascript", "/.js", &[ diff --git a/server/src/protocol/packet/session_list.rs b/server/src/protocol/packet/session_list.rs index f427115..bfaa814 100644 --- a/server/src/protocol/packet/session_list.rs +++ b/server/src/protocol/packet/session_list.rs @@ -63,6 +63,44 @@ pub struct PacketSessionListResponseRecord { pub is_turn:bool, pub is_complete:u8, } +impl PacketSessionListResponseRecord { + pub fn encode(&self) -> Vec + { + let mut output = self.token.to_vec(); + + let mut flags = 0u32; + flags |= self.player as u32; + flags |= (self.is_turn as u32) << 2; + flags |= (self.is_complete as u32) << 3; + + // Flags + output.append(&mut pack_u32(flags)); + + // Dawn handle + let mut bytes = self.handles[0].as_bytes().to_vec(); + output.append(&mut pack_u16(bytes.len() as u16)); + if bytes.len() > 0 { output.append(&mut bytes); } + + // Dusk handle + let mut bytes = self.handles[1].as_bytes().to_vec(); + output.append(&mut pack_u16(bytes.len() as u16)); + if bytes.len() > 0 { output.append(&mut bytes); } + + // Turn number + output.append(&mut pack_u16(self.turn)); + + // Last move + output.append(&mut pack_u32(self.last_move)); + + // Spectator count + output.append(&mut pack_u32(self.viewers)); + + // User is player + //chunk.append(&mut vec![record.player as u8]); + + output + } +} #[derive(Clone)] pub struct PacketSessionListResponse { @@ -82,41 +120,8 @@ impl Packet for PacketSessionListResponse { fn encode(&self) -> Vec { let mut result = pack_u16(self.records.len() as u16); - for record in &self.records { - let mut chunk = record.token.to_vec(); - - let mut flags = 0u32; - flags |= record.player as u32; - flags |= (record.is_turn as u32) << 2; - flags |= (record.is_complete as u32) << 3; - - // Flags - chunk.append(&mut pack_u32(flags)); - - // Dawn handle - let mut bytes = record.handles[0].as_bytes().to_vec(); - chunk.append(&mut pack_u16(bytes.len() as u16)); - if bytes.len() > 0 { chunk.append(&mut bytes); } - - // Dusk handle - let mut bytes = record.handles[1].as_bytes().to_vec(); - chunk.append(&mut pack_u16(bytes.len() as u16)); - if bytes.len() > 0 { chunk.append(&mut bytes); } - - // Turn number - chunk.append(&mut pack_u16(record.turn)); - - // Last move - chunk.append(&mut pack_u32(record.last_move)); - - // Spectator count - chunk.append(&mut pack_u32(record.viewers)); - - // User is player - //chunk.append(&mut vec![record.player as u8]); - - result.append(&mut chunk); + result.append(&mut record.encode()); } result } diff --git a/server/src/protocol/packet/user_info.rs b/server/src/protocol/packet/user_info.rs index a95cc5f..48879aa 100644 --- a/server/src/protocol/packet/user_info.rs +++ b/server/src/protocol/packet/user_info.rs @@ -1,10 +1,14 @@ -use crate::util::pack::pack_u16; +use crate::util::pack::{pack_u8, pack_u16}; -use super::Packet; +use super::{ + Packet, + PacketSessionListResponseRecord, +}; #[derive(Clone)] pub struct PacketUserInfo { pub handle:String, + } impl PacketUserInfo { pub fn new() -> Self @@ -28,6 +32,7 @@ pub struct PacketUserInfoResponse { pub status:u16, pub handle:String, pub is_online:bool, + pub history:Vec, } impl PacketUserInfoResponse { pub fn new() -> Self @@ -36,6 +41,7 @@ impl PacketUserInfoResponse { status:0, handle:String::new(), is_online:false, + history:Vec::new(), } } } @@ -44,8 +50,23 @@ impl Packet for PacketUserInfoResponse { fn encode(&self) -> Vec { + let handle_bytes = self.handle.as_bytes().to_vec(); + + let flags = self.is_online as u16; + + let mut history_bytes = pack_u16(self.history.len() as u16); + for record in &self.history { + history_bytes.append(&mut record.encode()); + } + [ pack_u16(self.status as u16), + pack_u16(flags), + + pack_u8(handle_bytes.len() as u8), + handle_bytes, + + history_bytes, ].concat() } } diff --git a/www/css/profile.css b/www/css/profile.css new file mode 100644 index 0000000..7a37b95 --- /dev/null +++ b/www/css/profile.css @@ -0,0 +1,25 @@ +main.profile>header { + display: block; + position: relative; + + width: 100%; + + background-color: #282828; + border-bottom: 1px solid #303030; +} + +main.profile>header>h1 { + display: block; + position: relative; + + padding: 1rem 2rem 1rem 2rem; + margin: 0; + + line-height: 3rem; + font-size: 2.5rem; + color: #f0f0f0; +} + +main.profile>section.history { + flex-grow: 1; +} diff --git a/www/css/text.css b/www/css/text.css new file mode 100644 index 0000000..2af9d39 --- /dev/null +++ b/www/css/text.css @@ -0,0 +1,60 @@ +main article.text{ + display:block; + position:relative; + width:100%; + flex-grow:1; + + padding:1rem; + margin:0; + + line-height:1.4em; + font-size:1.2rem; + color:#c0c0c0; + + overflow:auto; +} +main article.text>h1{ + padding:0.5rem; + margin:0 0 0.5rem 0; + + font-size:1.8rem; + font-weight:bold; + background-color:#a0a0a0; + color:#202020; +} +main article.text>h2{ + padding:0 0 0.5rem 0.25rem; + margin:1.5rem 0 0.5rem 0; + + font-size:1.6rem; + font-weight:bold; + border-bottom:2px solid #c0c0c0; + color:#c0c0c0; +} +main article.text>h3{ + padding:0 0 0 0.25rem; + margin:1.5rem 0 0.5rem 0; + + font-size:1.5rem; + font-weight:bold; + text-decoration:underline; + color:#b0b0b0; +} +main article.text>h4{ + padding:0 0 0 0.25rem; + margin:1.5rem 0 0.5rem 0; + + font-size:1.3rem; + text-decoration:underline; + color:#a0a0a0; +} +main article.text>p{ + padding:0 0.5rem 0 0.5rem; +} +main article.text a{ + color:#db758e; + text-decoration:none; +} +main article.text>a:hover{ + text-decoration:underline; +} diff --git a/www/css/ui.css b/www/css/ui.css index 60a22b3..be75b62 100644 --- a/www/css/ui.css +++ b/www/css/ui.css @@ -86,67 +86,6 @@ main table.list td>canvas { margin: 0 -1.5rem 0 -1.5rem; } -main article{ - display:block; - position:relative; - width:100%; - flex-grow:1; - - padding:1rem; - margin:0; - - line-height:1.4em; - font-size:1.2rem; - color:#c0c0c0; - - overflow:auto; -} -main article>h1{ - padding:0.5rem; - margin:0 0 0.5rem 0; - - font-size:1.8rem; - font-weight:bold; - background-color:#a0a0a0; - color:#202020; -} -main article>h2{ - padding:0 0 0.5rem 0.25rem; - margin:1.5rem 0 0.5rem 0; - - font-size:1.6rem; - font-weight:bold; - border-bottom:2px solid #c0c0c0; - color:#c0c0c0; -} -main article>h3{ - padding:0 0 0 0.25rem; - margin:1.5rem 0 0.5rem 0; - - font-size:1.5rem; - font-weight:bold; - text-decoration:underline; - color:#b0b0b0; -} -main article>h4{ - padding:0 0 0 0.25rem; - margin:1.5rem 0 0.5rem 0; - - font-size:1.3rem; - text-decoration:underline; - color:#a0a0a0; -} -main article>p{ - padding:0 0.5rem 0 0.5rem; -} -main article a{ - color:#db758e; - text-decoration:none; -} -main article>a:hover{ - text-decoration:underline; -} - main div.turn-slider-padding{ display:block; position:relative; diff --git a/www/js/scene.js b/www/js/scene.js index 9e53319..8f1b3ea 100644 --- a/www/js/scene.js +++ b/www/js/scene.js @@ -640,6 +640,7 @@ const SCENES = { let body = document.createElement("article"); body.setAttribute("id", "article"); + body.setAttribute("class", "text"); UI.maincontent(body); this.refresh("game.html"); @@ -668,6 +669,7 @@ const SCENES = { let body = document.createElement("article"); body.setAttribute("id", "article"); + body.setAttribute("class", "text"); UI.maincontent(body); this.refresh("main.html"); @@ -700,18 +702,27 @@ const SCENES = { Profile:class{ constructor() { - this.data = { - handle: "", - stats: { - games_played: 0, - }, - history: [ ], + this.handle = ""; + this.stats = { + games_played: 0, }; + this.history = [ ]; } - load(data) { - if(sessionStorage.getItem("auth") === null) return false; + /*preload(data) { + this.data.handle = data.handle; + MESSAGE_COMPOSE([ + PACK.u16(OpCode.UserInfo), + PACK.string(this.data.handle, PACK.u8), + ]); + return true; + }*/ + load(msg) { + /*if(msg.code != OpCode.UserInfo) { + return null; + }*/ + this.handle = msg.handle; - UI.mainmenu_account(data, "profile"); + UI.mainmenu_account(this.handle, "profile"); // Left Buttons let buttons_left = [ ]; @@ -722,8 +733,24 @@ const SCENES = { UI.mainnav(buttons_left, buttons_right); // Main Content + MAIN.setAttribute("class", "profile"); - history.pushState(null, "Dzura - About", "/u/" + data.handle); + let header = document.createElement("header"); + let title = document.createElement("h1"); + title.innerText = this.handle; + header.appendChild(title); + MAIN.appendChild(header); + + let table_stats = document.createElement("table"); + + let container_history = document.createElement("section"); + container_history.setAttribute("class", "history"); + let table_history = document.createElement("table"); + + container_history.appendChild(table_history); + MAIN.appendChild(container_history); + + history.pushState(null, "Dzura - About", "/u/" + this.handle); return true; } }, @@ -898,7 +925,7 @@ const SCENES = { // Resume / Review Buttons if(msg.data.player != 0) { if(this.mode == INTERFACE.Mode.Review) { - if(!data.view.is_complete) { + if(!msg.data.is_complete) { let callback_resume = function() { SCENE.load(SCENES.Game, { token:this.token, diff --git a/www/js/system.js b/www/js/system.js index ccf5c78..fcc3097 100644 --- a/www/js/system.js +++ b/www/js/system.js @@ -41,7 +41,6 @@ function RESUME() { secret, ]); } else { - console.log("HERE"); SCENE.load_url(); } } diff --git a/www/js/ui.js b/www/js/ui.js index 92141e3..93dcb46 100644 --- a/www/js/ui.js +++ b/www/js/ui.js @@ -189,16 +189,15 @@ const UI = { } }, - mainmenu_account(data, page) { + mainmenu_account(handle, page) { let buttons_top = [ ]; let buttons_bottom = [ ]; // Top Buttons buttons_top.push(UI.button("Profile", () => { SCENE.load(SCENES.Profile, { handle:CONTEXT.Auth.handle }) }, page == "profile")); - buttons_top.push(UI.button("History", () => { }, page == "history")); // Bottom Buttons - if(data === null || data.handle === CONTEXT.Auth.handle) { + if(CONTEXT.Auth !== null && (handle === null || handle == CONTEXT.Auth.handle)) { buttons_bottom.push(UI.button("Account", () => { SCENE.load(SCENES.Account) }, page == "account")); buttons_bottom.push(UI.button("Subscription", () => { SCENE.load(SCENES.Subscription) }, page == "subscription")); buttons_bottom.push(UI.button("Invitations", () => { SCENE.load(SCENES.Invitations) }, page == "invitations"));