diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 00000000..b06e564c --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,4 @@ +package-lock.json +node_modules/ +dist/ +.cache/ diff --git a/client/index.html b/client/index.html new file mode 100755 index 00000000..5c065ceb --- /dev/null +++ b/client/index.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/client/index.js b/client/index.js new file mode 100755 index 00000000..196992d6 --- /dev/null +++ b/client/index.js @@ -0,0 +1,19 @@ +const cbor = require('borc'); +const assert = require('assert'); +// Create WebSocket connection. +const ws = new WebSocket('ws://localhost:40000'); +ws.binaryType = 'arraybuffer'; + +// Connection opened +ws.addEventListener('open', function (event) { + ws.send(cbor.encode({ method: 'cryp_generate', params: { level: 64 }})); + ws.send(cbor.encode({ method: 'account_create', params: { name: 'ntr' }})); +}); + +// Listen for messages +ws.addEventListener('message', function (event) { + console.log('Message from server ', event.data); + const blob = new Uint8Array(event.data); + const decoded = cbor.decodeAll(blob); + console.log(decoded[0]); +}); \ No newline at end of file diff --git a/client/package.json b/client/package.json new file mode 100755 index 00000000..62fd850d --- /dev/null +++ b/client/package.json @@ -0,0 +1,17 @@ +{ + "name": "cryps-client", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "parcel index.html", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "UNLICENSED", + "dependencies": { + "borc": "^2.0.3", + "cbor": "^4.1.1", + "parcel": "^1.9.7" + } +} diff --git a/ops/.gitkeep b/ops/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/ops/00000000000000_diesel_initial_setup/down.sql b/ops/00000000000000_diesel_initial_setup/down.sql new file mode 100644 index 00000000..a9f52609 --- /dev/null +++ b/ops/00000000000000_diesel_initial_setup/down.sql @@ -0,0 +1,6 @@ +-- This file was automatically created by Diesel to setup helper functions +-- and other internal bookkeeping. This file is safe to edit, any future +-- changes will be added to existing projects as new migrations. + +DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); +DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/ops/00000000000000_diesel_initial_setup/up.sql b/ops/00000000000000_diesel_initial_setup/up.sql new file mode 100644 index 00000000..d68895b1 --- /dev/null +++ b/ops/00000000000000_diesel_initial_setup/up.sql @@ -0,0 +1,36 @@ +-- This file was automatically created by Diesel to setup helper functions +-- and other internal bookkeeping. This file is safe to edit, any future +-- changes will be added to existing projects as new migrations. + + + + +-- Sets up a trigger for the given table to automatically set a column called +-- `updated_at` whenever the row is modified (unless `updated_at` was included +-- in the modified columns) +-- +-- # Example +-- +-- ```sql +-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); +-- +-- SELECT diesel_manage_updated_at('users'); +-- ``` +CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ +BEGIN + EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s + FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ +BEGIN + IF ( + NEW IS DISTINCT FROM OLD AND + NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at + ) THEN + NEW.updated_at := current_timestamp; + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; diff --git a/ops/2018-09-11-113648_create_lobbies/down.sql b/ops/2018-09-11-113648_create_lobbies/down.sql new file mode 100755 index 00000000..62b267e6 --- /dev/null +++ b/ops/2018-09-11-113648_create_lobbies/down.sql @@ -0,0 +1 @@ +DROP TABLE lobbies; \ No newline at end of file diff --git a/ops/2018-09-11-113648_create_lobbies/up.sql b/ops/2018-09-11-113648_create_lobbies/up.sql new file mode 100755 index 00000000..c0e4cd3e --- /dev/null +++ b/ops/2018-09-11-113648_create_lobbies/up.sql @@ -0,0 +1,6 @@ +CREATE TABLE lobbies ( + id uuid PRIMARY KEY, + a uuid NOT NULL, + b uuid, + data bytea +); diff --git a/server/.cargo/config b/server/.cargo/config new file mode 100755 index 00000000..3c3311fc --- /dev/null +++ b/server/.cargo/config @@ -0,0 +1,3 @@ +[target.x86_64-pc-windows-msvc.gnu] +rustc-link-search = ["C:\\Program Files\\PostgreSQL\\pg96\\lib"] + diff --git a/server/.env b/server/.env new file mode 100755 index 00000000..f42f5c28 --- /dev/null +++ b/server/.env @@ -0,0 +1 @@ +DATABASE_URL=postgres://cryps:craftbeer@localhost/cryps diff --git a/.gitignore b/server/.gitignore similarity index 100% rename from .gitignore rename to server/.gitignore diff --git a/Cargo.toml b/server/Cargo.toml similarity index 68% rename from Cargo.toml rename to server/Cargo.toml index edbb45ab..ba15b57b 100755 --- a/Cargo.toml +++ b/server/Cargo.toml @@ -10,4 +10,10 @@ serde = "1" serde_derive = "1" serde_cbor = "0.9" ws = "*" + +dotenv = "0.9.0" env_logger = "*" + +r2d2 = "0.8.2" +r2d2_sqlite = "0.6" +rusqlite = { version = "0.14.0", features = ["bundled"] } diff --git a/DIARY.md b/server/DIARY.md similarity index 100% rename from DIARY.md rename to server/DIARY.md diff --git a/README.md b/server/README.md similarity index 100% rename from README.md rename to server/README.md diff --git a/WORKLOG.md b/server/WORKLOG.md old mode 100644 new mode 100755 similarity index 62% rename from WORKLOG.md rename to server/WORKLOG.md index 557cfdf9..65aaa642 --- a/WORKLOG.md +++ b/server/WORKLOG.md @@ -1,10 +1,13 @@ * Battling - * Cryp Serialisation - * RPC * Logins * Cryp Ownership * Matchmaking + * Lobbies + * Create + * Join + * Resolve * Stats + * Missions * Cryp Generation * diff --git a/src/battle.rs b/server/src/battle.rs similarity index 100% rename from src/battle.rs rename to server/src/battle.rs diff --git a/src/combat.rs b/server/src/combat.rs similarity index 88% rename from src/combat.rs rename to server/src/combat.rs index f0c9a1a1..d10ffbc9 100755 --- a/src/combat.rs +++ b/server/src/combat.rs @@ -91,16 +91,22 @@ pub fn test_battle() { #[cfg(test)] mod tests { - use *; + use super::*; #[test] fn pve_test() { - // let player = Cryp::new() - // .named("ca phe sua da".to_string()) - // .level(2) - // .create(); + let player = Cryp::new() + .named("ca phe sua da".to_string()) + .level(2) + .create(); - // levelling(player); + levelling(player); + return; + } + + #[test] + fn battle_test() { + test_battle(); return; } diff --git a/src/cryp.rs b/server/src/cryp.rs similarity index 100% rename from src/cryp.rs rename to server/src/cryp.rs diff --git a/src/main.rs b/server/src/main.rs similarity index 65% rename from src/main.rs rename to server/src/main.rs index 8e1b515b..29b79bba 100755 --- a/src/main.rs +++ b/server/src/main.rs @@ -3,6 +3,12 @@ extern crate uuid; extern crate ws; extern crate env_logger; +// #[macro_use] +// extern crate dotenv; +extern crate r2d2; +extern crate r2d2_sqlite; +extern crate rusqlite; + extern crate serde; extern crate serde_cbor; #[macro_use] @@ -14,6 +20,7 @@ mod net; mod combat; mod skill; mod rpc; +mod user; use net::{start}; diff --git a/src/net.rs b/server/src/net.rs similarity index 65% rename from src/net.rs rename to server/src/net.rs index f8688ae4..7e408557 100755 --- a/src/net.rs +++ b/server/src/net.rs @@ -1,11 +1,19 @@ -use cryp::{generate}; use ws::{listen, Handler, Sender, Result, Message, Handshake, CloseCode, Error}; -use rpc::{Rpc,RpcMessage}; use serde_cbor::{to_vec}; +use r2d2::{Pool}; +use r2d2::{PooledConnection}; +use r2d2_sqlite::{SqliteConnectionManager}; + +pub type Db = PooledConnection; + +use cryp::{generate}; +use rpc::{Rpc,RpcMessage}; + struct Server { out: Sender, rpc: Rpc, + db: Pool, } impl Handler for Server { @@ -15,7 +23,8 @@ impl Handler for Server { } fn on_message(&mut self, msg: Message) -> Result<()> { - let reply = self.rpc.receive(msg); + let db = self.db.get().expect("unable to get db connection"); + let reply = self.rpc.receive(msg, db); println!("{:?}", reply); self.out.send(reply.unwrap()) } @@ -36,5 +45,11 @@ impl Handler for Server { } pub fn start() { - listen("127.0.0.1:40000", |out| { Server { out, rpc: Rpc {} } }).unwrap(); -} \ No newline at end of file + let manager = SqliteConnectionManager::file("/var/cryps/cryps.db"); + + let pool = Pool::builder() + .build(manager) + .expect("Failed to create pool."); + + listen("127.0.0.1:40000", |out| { Server { out, rpc: Rpc {}, db: pool.clone() } }).unwrap(); +} diff --git a/src/rpc.rs b/server/src/rpc.rs similarity index 57% rename from src/rpc.rs rename to server/src/rpc.rs index 6f8bb352..de1f440e 100644 --- a/src/rpc.rs +++ b/server/src/rpc.rs @@ -3,23 +3,14 @@ use ws::{Message}; use serde_cbor::{from_slice}; use serde_cbor::error::Error as CborError; +use net::Db; use cryp::generate; +use user::{create}; pub struct Rpc; -#[derive(Debug,Clone,Serialize,Deserialize)] -struct GenerateMsg { - method: String, - params: GenerateParams, -} - -#[derive(Debug,Clone,Serialize,Deserialize)] -pub struct GenerateParams { - pub level: u8, -} - impl Rpc { - pub fn receive(&self, msg: Message) -> StdResult, RpcError> { + pub fn receive(&self, msg: Message, db: Db) -> StdResult, RpcError> { // consume the ws data into bytes let data = msg.into_data(); @@ -36,6 +27,13 @@ impl Rpc { Err(_) => Err(RpcError::Parse), } }, + "account_create" => { + match from_slice::(&data) { + Ok(v) => Ok(create(v.params, db)), + Err(_) => Err(RpcError::Parse), + } + }, + _ => Err(RpcError::UnknownMethod), } }, @@ -55,15 +53,38 @@ pub enum RpcError { UnknownMethod, } -#[cfg(test)] -mod tests { - use super::*; - use serde_cbor::to_vec; - #[test] - fn rpc_parse() { - let rpc = Rpc {}; - let msg = GenerateMsg { method: "cryp_generate".to_string(), params: GenerateParams { level: 64 } }; - let v = to_vec(&msg).unwrap(); - let received = rpc.receive(Message::Binary(v)); - } -} \ No newline at end of file +#[derive(Debug,Clone,Serialize,Deserialize)] +struct GenerateMsg { + method: String, + params: GenerateParams, +} + +#[derive(Debug,Clone,Serialize,Deserialize)] +pub struct GenerateParams { + pub level: u8, +} + +#[derive(Debug,Clone,Serialize,Deserialize)] +struct AccountCreateMsg { + method: String, + params: AccountCreateParams, +} + +#[derive(Debug,Clone,Serialize,Deserialize)] +pub struct AccountCreateParams { + pub name: String, +} + + +// #[cfg(test)] +// mod tests { +// use super::*; +// use serde_cbor::to_vec; +// #[test] +// fn rpc_parse() { +// let rpc = Rpc {}; +// let msg = GenerateMsg { method: "cryp_generate".to_string(), params: GenerateParams { level: 64 } }; +// let v = to_vec(&msg).unwrap(); +// let received = rpc.receive(Message::Binary(v)); +// } +// } \ No newline at end of file diff --git a/src/skill.rs b/server/src/skill.rs similarity index 100% rename from src/skill.rs rename to server/src/skill.rs diff --git a/server/src/user.rs b/server/src/user.rs new file mode 100644 index 00000000..63f2254c --- /dev/null +++ b/server/src/user.rs @@ -0,0 +1,29 @@ +use serde_cbor::to_vec; +use uuid::Uuid; + +use net::Db; +use rpc::{AccountCreateParams}; + +struct User { + name: String, + id: Uuid, +} + +pub fn create(params: AccountCreateParams, db: Db) -> Vec { + let uuid = Uuid::new_v4(); + let user = User { + id: uuid, + name: params.name, + }; + + let entry = db.execute("INSERT INTO users (id, name) + VALUES (?1, ?2)", + &[&user.id.to_string(), &user.name]).unwrap(); + + println!("{:?}", entry); + + match to_vec(&true) { + Ok(v) => v, + Err(e) => panic!("couldn't serialize cryp"), + } +}