diff --git a/client/src/components/cryp.list.jsx b/client/src/components/cryp.list.jsx
index 294fc6d0..a3b57604 100644
--- a/client/src/components/cryp.list.jsx
+++ b/client/src/components/cryp.list.jsx
@@ -33,7 +33,6 @@ function CrypPanel({ cryps, sendCombatPve }) {
diff --git a/client/src/main.jsx b/client/src/main.jsx
index 15b1bfb9..4e3c6505 100755
--- a/client/src/main.jsx
+++ b/client/src/main.jsx
@@ -26,6 +26,7 @@ store.subscribe(() => console.log(store.getState()));
const ws = createSocket(store);
store.dispatch(actions.setWs(ws));
+ws.connect();
// tells jdenticon to look for new svgs and render them
// so we don't have to setInnerHtml or manually call update
diff --git a/client/src/socket.jsx b/client/src/socket.jsx
index e8b9f199..62686db4 100644
--- a/client/src/socket.jsx
+++ b/client/src/socket.jsx
@@ -16,8 +16,34 @@ function errorToast(err) {
// requires the redux store in order to push updates
// to components
function createSocket(store) {
- const ws = new WebSocket('ws://localhost:40000');
- ws.binaryType = 'arraybuffer';
+ let ws;
+
+ function connect() {
+ ws = new WebSocket('ws://localhost:40000');
+ ws.binaryType = 'arraybuffer';
+
+ // Connection opened
+ ws.addEventListener('open', function wsOpen(event) {
+ send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } });
+ });
+
+ // Listen for messages
+ ws.addEventListener('message', onMessage);
+
+ ws.addEventListener('error', function wsError(event) {
+ console.error('WebSocket error', event);
+ account = null;
+ // return setTimeout(connect, 5000);
+ });
+
+ ws.addEventListener('close', function wsClose(event) {
+ console.error('WebSocket closed', event);
+ account = null;
+ return setTimeout(connect, 5000);
+ });
+
+ return ws;
+ }
// handle account auth within the socket itself
// https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html
@@ -103,27 +129,10 @@ function createSocket(store) {
return handlers[method](params);
}
- // Connection opened
- ws.addEventListener('open', function wsOpen(event) {
- send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } });
- });
-
- // Listen for messages
- ws.addEventListener('message', onMessage);
-
- ws.addEventListener('error', function wsError(event) {
- console.error('WebSocket error', event);
- account = null;
- });
-
- ws.addEventListener('close', function wsClose(event) {
- console.error('WebSocket closed', event);
- account = null;
- });
-
return {
sendAccountLogin,
sendCombatPve,
+ connect,
};
}
diff --git a/server/WORKLOG.md b/server/WORKLOG.md
index 1ad4ff5b..3cd8e97c 100755
--- a/server/WORKLOG.md
+++ b/server/WORKLOG.md
@@ -1,7 +1,7 @@
* Battling
* QOL
* auto login
- * ws reconnect
+ * ws reconnect ✔️
* Levelling
* Global rolls
* Logins ✔️
diff --git a/server/src/battle.rs b/server/src/battle.rs
index d190911d..ef9779ae 100755
--- a/server/src/battle.rs
+++ b/server/src/battle.rs
@@ -1,4 +1,4 @@
-// use uuid::Uuid;
+use uuid::Uuid;
// use rand::prelude::*;
use cryp::Cryp;
@@ -14,48 +14,55 @@ use cryp::Cryp;
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Battle {
- pub a: Cryp,
- pub b: Cryp,
+ pub a: Cryp,
+ pub b: Cryp,
}
impl Battle {
- pub fn new(a: &Cryp, b: &Cryp) -> Battle {
- return Battle {
- a: a.clone(),
- b: b.clone(),
- };
- }
-
- pub fn cryps(&self) -> Vec<&Cryp> {
- vec![&self.a, &self.b]
- }
-
- pub fn next(&mut self) -> &mut Battle {
- if self.finished() {
- panic!("{:?} is finished", self);
+ pub fn new(a: &Cryp, b: &Cryp) -> Battle {
+ return Battle {
+ a: a.clone(),
+ b: b.clone(),
+ };
}
- let a_turn = self.a.turn();
- let b_turn = self.b.turn();
-
- self.a.assign_dmg(&self.b, &a_turn, &b_turn);
- self.b.assign_dmg(&self.a, &b_turn, &a_turn);
-
- self
- }
-
- pub fn finished(&self) -> bool {
- self.cryps().iter().any(|c| c.is_ko())
- }
-
- pub fn winner(&self) -> Option<&Cryp> {
- if self.cryps().iter().all(|c| c.is_ko()) {
- return None
+ pub fn cryps(&self) -> Vec<&Cryp> {
+ vec![&self.a, &self.b]
}
- match self.cryps().iter().find(|c| !c.is_ko()) {
- Some(w) => Some(w),
- None => panic!("no winner found {:?}", self),
+ pub fn next(&mut self) -> &mut Battle {
+ if self.finished() {
+ panic!("{:?} is finished", self);
+ }
+
+ let a_turn = self.a.turn();
+ let b_turn = self.b.turn();
+
+ self.a.assign_dmg(&self.b, &a_turn, &b_turn);
+ self.b.assign_dmg(&self.a, &b_turn, &a_turn);
+
+ self
+ }
+
+ pub fn finished(&self) -> bool {
+ self.cryps().iter().any(|c| c.is_ko())
+ }
+
+ pub fn cryp_by_id(&self, id: Uuid) -> &Cryp {
+ match self.cryps().iter().find(|c| c.id == id) {
+ Some(c) => c,
+ None => panic!("cryp not in battle {:?}", self),
+ }
+ }
+
+ pub fn winner(&self) -> Option<&Cryp> {
+ if self.cryps().iter().all(|c| c.is_ko()) {
+ return None
+ }
+
+ match self.cryps().iter().find(|c| !c.is_ko()) {
+ Some(w) => Some(w),
+ None => panic!("no winner found {:?}", self),
+ }
}
- }
}
diff --git a/server/src/combat.rs b/server/src/combat.rs
index 1c4e7edf..8ce03fb4 100755
--- a/server/src/combat.rs
+++ b/server/src/combat.rs
@@ -1,6 +1,7 @@
-use ws::{Sender};
+use std::{thread, time};
+
use rand::prelude::*;
-use serde_cbor::{from_slice, to_vec};
+use serde_cbor::{from_slice};
// Db Commons
use failure::Error;
@@ -113,29 +114,32 @@ where F: Fn(&Battle) -> Result<(), Error>
// tells from_slice to cast into a cryp
let cryp_bytes: Vec = returned.get("data");
- let mut plr: Cryp = from_slice::(&cryp_bytes)?;
+ let plr: Cryp = from_slice::(&cryp_bytes)?;
let mob = generate_mob(&plr);
let mut battle = Battle::new(&plr, &mob);
loop {
- battle.next();
+ battle.next();
- send(&battle)?;
+ send(&battle)?;
- if battle.finished() {
+ if battle.finished() {
let success = match battle.winner() {
Some(c) => c.id == plr.id,
None => false,
};
+ let mut post_battle_plr = battle.cryp_by_id(plr.id).clone();
+
if success {
- plr = plr.add_xp();
- write_cryp(plr, db, account)?;
+ post_battle_plr = post_battle_plr.add_xp();
}
+ write_cryp(post_battle_plr, db, account)?;
+
break Ok(battle)
- }
+ }
}
}
diff --git a/server/src/rpc.rs b/server/src/rpc.rs
index 4feed4be..cad78566 100755
--- a/server/src/rpc.rs
+++ b/server/src/rpc.rs
@@ -31,79 +31,90 @@ impl Rpc {
// now we have the method name
// match on that to determine what fn to call
match v.method.as_ref() {
- "cryp_spawn" => {
- match from_slice::(&data) {
- Ok(v) => {
- match account {
- Some(u) => Ok(RpcResponse {
- method: v.method,
- params: RpcResult::SpawnCryp(spawn(v.params, db, u)?)
- }),
- None => Err(err_msg("auth required")),
- }
- }
- Err(_e) => Err(err_msg("invalid params")),
- }
- },
- "combat_pve" => {
- let send = |b: &Battle| -> Result<(), Error> {
- let reply = RpcResponse {
- method: "battle_state".to_string(),
- params: RpcResult::Pve(b.clone())
- };
- let response = to_vec(&reply)?;
- match out.send(response) {
- Ok(()) => Ok(()),
- Err(e) => Err(err_msg(e))
- }
- };
+ "cryp_spawn" => Rpc::cryp_spawn(data, db, account),
+ "combat_pve" => Rpc::combat_pve(data, db, account, out),
+ "account_create" => Rpc::account_create(data, db),
+ "account_login" => Rpc::account_login(data, db),
+ "account_cryps" => Rpc::account_cryps(db, account),
- match from_slice::(&data) {
- Ok(v) => {
- match account {
- Some(u) => Ok(RpcResponse {
- method: v.method,
- params: RpcResult::Pve(pve(v.params, db, u, send)?)
- }),
- None => Err(err_msg("auth required")),
- }
- }
- Err(_e) => Err(err_msg("invalid params")),
- }
- },
- "account_create" => {
- match from_slice::(&data) {
- Ok(v) => Ok(RpcResponse {
- method: v.method,
- params: RpcResult::Account(create(v.params, db)?)
- }),
- Err(_e) => Err(err_msg("invalid params")),
- }
- },
- "account_login" => {
- match from_slice::(&data) {
- Ok(v) => Ok(RpcResponse {
- method: v.method,
- params: RpcResult::Account(login(v.params, db)?)
- }),
- Err(_e) => Err(err_msg("invalid params")),
- }
- },
- "account_cryps" => {
- match account {
- Some(u) => Ok(RpcResponse {
- method: v.method,
- params: RpcResult::CrypList(fetch_cryps(db, u)?)
- }),
- None => Err(err_msg("auth required")),
- }
- },
_ => Err(err_msg("unknown method")),
}
},
Err(_e) => Err(err_msg("invalid message")),
}
}
+
+ fn combat_pve(data: Vec, db: Db, account: Option, out: &Sender) -> Result {
+ let send = |b: &Battle| -> Result<(), Error> {
+ let reply = RpcResponse {
+ method: "battle_state".to_string(),
+ params: RpcResult::Pve(b.clone())
+ };
+ let response = to_vec(&reply)?;
+ match out.send(response) {
+ Ok(()) => Ok(()),
+ Err(e) => Err(err_msg(e))
+ }
+ };
+
+ match from_slice::(&data) {
+ Ok(v) => {
+ match account {
+ Some(u) => Ok(RpcResponse {
+ method: v.method,
+ params: RpcResult::Pve(pve(v.params, db, u, send)?)
+ }),
+ None => Err(err_msg("auth required")),
+ }
+ }
+ Err(_e) => Err(err_msg("invalid params")),
+ }
+ }
+
+ fn cryp_spawn(data: Vec, db: Db, account: Option) -> Result {
+ match from_slice::(&data) {
+ Ok(v) => {
+ match account {
+ Some(u) => Ok(RpcResponse {
+ method: v.method,
+ params: RpcResult::SpawnCryp(spawn(v.params, db, u)?)
+ }),
+ None => Err(err_msg("auth required")),
+ }
+ }
+ Err(_e) => Err(err_msg("invalid params")),
+ }
+ }
+
+ fn account_create(data: Vec, db: Db) -> Result {
+ match from_slice::(&data) {
+ Ok(v) => Ok(RpcResponse {
+ method: v.method,
+ params: RpcResult::Account(create(v.params, db)?)
+ }),
+ Err(_e) => Err(err_msg("invalid params")),
+ }
+ }
+
+ fn account_login(data: Vec, db: Db) -> Result {
+ match from_slice::(&data) {
+ Ok(v) => Ok(RpcResponse {
+ method: v.method,
+ params: RpcResult::Account(login(v.params, db)?)
+ }),
+ Err(_e) => Err(err_msg("invalid params")),
+ }
+ }
+
+ fn account_cryps(db: Db, account: Option) -> Result {
+ match account {
+ Some(u) => Ok(RpcResponse {
+ method: "account_cryps".to_string(),
+ params: RpcResult::CrypList(fetch_cryps(db, u)?)
+ }),
+ None => Err(err_msg("auth required")),
+ }
+ }
}
#[derive(Debug,Clone,Serialize,Deserialize)]