rework rpc

This commit is contained in:
ntr 2018-10-08 23:26:28 +11:00
parent c950a0a866
commit 4d862a7900
7 changed files with 165 additions and 134 deletions

View File

@ -33,7 +33,6 @@ function CrypPanel({ cryps, sendCombatPve }) {
<div> <div>
<a className="button is-large is-fullwidth"> <a className="button is-large is-fullwidth">
<span>Spawn 👾</span> <span>Spawn 👾</span>
<span className="icon is-medium"><i className="fab fa-plus"></i></span>
</a> </a>
{crypPanels} {crypPanels}
</div> </div>

View File

@ -26,6 +26,7 @@ store.subscribe(() => console.log(store.getState()));
const ws = createSocket(store); const ws = createSocket(store);
store.dispatch(actions.setWs(ws)); store.dispatch(actions.setWs(ws));
ws.connect();
// tells jdenticon to look for new svgs and render them // tells jdenticon to look for new svgs and render them
// so we don't have to setInnerHtml or manually call update // so we don't have to setInnerHtml or manually call update

View File

@ -16,9 +16,35 @@ function errorToast(err) {
// requires the redux store in order to push updates // requires the redux store in order to push updates
// to components // to components
function createSocket(store) { function createSocket(store) {
const ws = new WebSocket('ws://localhost:40000'); let ws;
function connect() {
ws = new WebSocket('ws://localhost:40000');
ws.binaryType = 'arraybuffer'; 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 // handle account auth within the socket itself
// https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html // https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html
let account = null; let account = null;
@ -103,27 +129,10 @@ function createSocket(store) {
return handlers[method](params); 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 { return {
sendAccountLogin, sendAccountLogin,
sendCombatPve, sendCombatPve,
connect,
}; };
} }

View File

@ -1,7 +1,7 @@
* Battling * Battling
* QOL * QOL
* auto login * auto login
* ws reconnect * ws reconnect ✔️
* Levelling * Levelling
* Global rolls * Global rolls
* Logins ✔️ * Logins ✔️

View File

@ -1,4 +1,4 @@
// use uuid::Uuid; use uuid::Uuid;
// use rand::prelude::*; // use rand::prelude::*;
use cryp::Cryp; use cryp::Cryp;
@ -48,6 +48,13 @@ impl Battle {
self.cryps().iter().any(|c| c.is_ko()) 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> { pub fn winner(&self) -> Option<&Cryp> {
if self.cryps().iter().all(|c| c.is_ko()) { if self.cryps().iter().all(|c| c.is_ko()) {
return None return None

View File

@ -1,6 +1,7 @@
use ws::{Sender}; use std::{thread, time};
use rand::prelude::*; use rand::prelude::*;
use serde_cbor::{from_slice, to_vec}; use serde_cbor::{from_slice};
// Db Commons // Db Commons
use failure::Error; use failure::Error;
@ -113,7 +114,7 @@ where F: Fn(&Battle) -> Result<(), Error>
// tells from_slice to cast into a cryp // tells from_slice to cast into a cryp
let cryp_bytes: Vec<u8> = returned.get("data"); let cryp_bytes: Vec<u8> = returned.get("data");
let mut plr: Cryp = from_slice::<Cryp>(&cryp_bytes)?; let plr: Cryp = from_slice::<Cryp>(&cryp_bytes)?;
let mob = generate_mob(&plr); let mob = generate_mob(&plr);
let mut battle = Battle::new(&plr, &mob); let mut battle = Battle::new(&plr, &mob);
@ -129,11 +130,14 @@ where F: Fn(&Battle) -> Result<(), Error>
None => false, None => false,
}; };
let mut post_battle_plr = battle.cryp_by_id(plr.id).clone();
if success { if success {
plr = plr.add_xp(); post_battle_plr = post_battle_plr.add_xp();
write_cryp(plr, db, account)?;
} }
write_cryp(post_battle_plr, db, account)?;
break Ok(battle) break Ok(battle)
} }
} }

View File

@ -31,21 +31,20 @@ impl Rpc {
// now we have the method name // now we have the method name
// match on that to determine what fn to call // match on that to determine what fn to call
match v.method.as_ref() { match v.method.as_ref() {
"cryp_spawn" => { "cryp_spawn" => Rpc::cryp_spawn(data, db, account),
match from_slice::<CrypSpawnMsg>(&data) { "combat_pve" => Rpc::combat_pve(data, db, account, out),
Ok(v) => { "account_create" => Rpc::account_create(data, db),
match account { "account_login" => Rpc::account_login(data, db),
Some(u) => Ok(RpcResponse { "account_cryps" => Rpc::account_cryps(db, account),
method: v.method,
params: RpcResult::SpawnCryp(spawn(v.params, db, u)?) _ => Err(err_msg("unknown method")),
}),
None => Err(err_msg("auth required")),
}
}
Err(_e) => Err(err_msg("invalid params")),
} }
}, },
"combat_pve" => { Err(_e) => Err(err_msg("invalid message")),
}
}
fn combat_pve(data: Vec<u8>, db: Db, account: Option<Account>, out: &Sender) -> Result<RpcResponse, Error> {
let send = |b: &Battle| -> Result<(), Error> { let send = |b: &Battle| -> Result<(), Error> {
let reply = RpcResponse { let reply = RpcResponse {
method: "battle_state".to_string(), method: "battle_state".to_string(),
@ -70,8 +69,24 @@ impl Rpc {
} }
Err(_e) => Err(err_msg("invalid params")), Err(_e) => Err(err_msg("invalid params")),
} }
}, }
"account_create" => {
fn cryp_spawn(data: Vec<u8>, db: Db, account: Option<Account>) -> Result<RpcResponse, Error> {
match from_slice::<CrypSpawnMsg>(&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<u8>, db: Db) -> Result<RpcResponse, Error> {
match from_slice::<AccountCreateMsg>(&data) { match from_slice::<AccountCreateMsg>(&data) {
Ok(v) => Ok(RpcResponse { Ok(v) => Ok(RpcResponse {
method: v.method, method: v.method,
@ -79,8 +94,9 @@ impl Rpc {
}), }),
Err(_e) => Err(err_msg("invalid params")), Err(_e) => Err(err_msg("invalid params")),
} }
}, }
"account_login" => {
fn account_login(data: Vec<u8>, db: Db) -> Result<RpcResponse, Error> {
match from_slice::<AccountLoginMsg>(&data) { match from_slice::<AccountLoginMsg>(&data) {
Ok(v) => Ok(RpcResponse { Ok(v) => Ok(RpcResponse {
method: v.method, method: v.method,
@ -88,21 +104,16 @@ impl Rpc {
}), }),
Err(_e) => Err(err_msg("invalid params")), Err(_e) => Err(err_msg("invalid params")),
} }
}, }
"account_cryps" => {
fn account_cryps(db: Db, account: Option<Account>) -> Result<RpcResponse, Error> {
match account { match account {
Some(u) => Ok(RpcResponse { Some(u) => Ok(RpcResponse {
method: v.method, method: "account_cryps".to_string(),
params: RpcResult::CrypList(fetch_cryps(db, u)?) params: RpcResult::CrypList(fetch_cryps(db, u)?)
}), }),
None => Err(err_msg("auth required")), None => Err(err_msg("auth required")),
} }
},
_ => Err(err_msg("unknown method")),
}
},
Err(_e) => Err(err_msg("invalid message")),
}
} }
} }