152 lines
4.1 KiB
JavaScript
152 lines
4.1 KiB
JavaScript
const { toast } = require('bulma-toast');
|
|
const cbor = require('borc');
|
|
|
|
const actions = require('./actions');
|
|
|
|
function errorToast(err) {
|
|
console.error(err);
|
|
return toast({
|
|
message: err,
|
|
type: 'is-warning',
|
|
duration: 5000,
|
|
});
|
|
}
|
|
|
|
// Create WebSocket connection.
|
|
// requires the redux store in order to push updates
|
|
// to components
|
|
function createSocket(store) {
|
|
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
|
|
let account = null;
|
|
|
|
// -------------
|
|
// Incoming
|
|
// -------------
|
|
function accountLogin(res) {
|
|
const [struct, login] = res;
|
|
|
|
account = login;
|
|
store.dispatch(actions.setAccount(login));
|
|
// send({ method: 'cryp_spawn', params: { name: 'muji' } });
|
|
send({ method: 'account_cryps', params: {} });
|
|
send({ method: 'item_list', params: {}});
|
|
console.log(account);
|
|
}
|
|
|
|
function accountCryps(response) {
|
|
const [structName, cryps] = response;
|
|
store.dispatch(actions.setCryps(cryps));
|
|
console.log('got my cryps', cryps);
|
|
}
|
|
|
|
function battleState(response) {
|
|
const [structName, battle] = response;
|
|
store.dispatch(actions.setBattle(battle));
|
|
}
|
|
|
|
function crypSpawn(response) {
|
|
const [structName, cryp] = response;
|
|
console.log('got a new cryp', cryp);
|
|
}
|
|
|
|
function combatPve(response) {
|
|
const [structName, battle] = response;
|
|
console.log('got a new battle', battle);
|
|
}
|
|
|
|
function itemList(response) {
|
|
const [structName, items] = response;
|
|
store.dispatch(actions.setItems(items));
|
|
}
|
|
|
|
// -------------
|
|
// Outgoing
|
|
// -------------
|
|
function send(msg) {
|
|
msg.token = account && account.token;
|
|
ws.send(cbor.encode(msg));
|
|
}
|
|
|
|
function sendAccountLogin(name, password) {
|
|
send({ method: 'account_login', params: { name, password } });
|
|
}
|
|
|
|
function sendCrypSpawn(name) {
|
|
send({ method: 'cryp_spawn', params: { name } });
|
|
}
|
|
|
|
function sendCombatPve(id) {
|
|
send({ method: 'combat_pve', params: { id } });
|
|
}
|
|
|
|
|
|
// -------------
|
|
// Handling
|
|
// -------------
|
|
// when the server sends a reply it will have one of these message types
|
|
// this object wraps the reply types to a function
|
|
const handlers = {
|
|
cryp_spawn: crypSpawn,
|
|
combat_pve: combatPve,
|
|
battle_state: battleState,
|
|
account_login: accountLogin,
|
|
account_create: accountLogin,
|
|
account_cryps: accountCryps,
|
|
item_list: itemList,
|
|
};
|
|
|
|
// decodes the cbor and
|
|
// calls the handlers defined above based on message type
|
|
function onMessage(event) {
|
|
// decode binary msg from server
|
|
const blob = new Uint8Array(event.data);
|
|
const res = cbor.decode(blob);
|
|
console.log(res);
|
|
|
|
// check for error and split into response type and data
|
|
if (res.err) return errorToast(res.err);
|
|
const { method, params } = res;
|
|
if (!handlers[method]) return errorToast(`${method} handler missing`);
|
|
return handlers[method](params);
|
|
}
|
|
|
|
return {
|
|
sendAccountLogin,
|
|
sendCombatPve,
|
|
sendCrypSpawn,
|
|
connect,
|
|
};
|
|
}
|
|
|
|
module.exports = createSocket;
|