Skip to content
Open

p2p #13

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ canisters/
.dfx/

# frontend code
package-lock.json
node_modules/
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ Click the above icon to play online!
- `dfx build`
- `dfx canister install --all`
- visit `127.0.0.1:8000/?canisterId={maze_assets_canister_id}`

# Start peerjs server locally

- install: `npm install peer -g`
- `peerjs --port 9000 --key peerjs --path /myapp`
13 changes: 8 additions & 5 deletions src/main.mo
Original file line number Diff line number Diff line change
Expand Up @@ -173,20 +173,23 @@ actor {
let id = msg.caller;
maze.move(id, dir);
};
// Not needed. For debugging only
public query func getState() : async [OutputState] {
maze.outputState()
};
// Output:
// - Array of non-empty cells
// - Processed sequence number
// - Processed sequence number
public query(msg) func getMap() : async ([OutputGrid], Nat) {
(maze.outputMap(), maze.getSeq(msg.caller))
};
public query(msg) func fakeMove(dirs : [Msg]) : async ([OutputGrid], Nat) {
let id = msg.caller;
// query move takes pending moves from all players
public query(msg) func fakeMove(dirs : [(Principal, [Msg])]) : async ([OutputGrid], Nat) {
let processedSeq = maze.getSeq(msg.caller);
for (dir in dirs.vals()) {
maze.move(id, dir);
for ((id, msgs) in dirs.vals()) {
for (m in msgs.vals()) {
maze.move(id, m);
};
};
(maze.outputMap(), processedSeq)
};
Expand Down
88 changes: 77 additions & 11 deletions src/maze_assets/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import canister from 'ic:canisters/maze';
import './maze.css';
import { CanisterId } from '@dfinity/agent';

// util for creating maze

Expand All @@ -8,7 +9,6 @@ const N = 10;
const symbols = [ "", "wall", "hero" ];

async function generateMaze(dom) {
console.log("generateMaze");
let f = await canister.getMap();
// First create the empty map
for (let i = 0; i < N; i++) {
Expand Down Expand Up @@ -56,26 +56,59 @@ async function mazeKeyPressHandler(e) {
const msg = {};
msg.seq = myseq++;
msg.dir = dir;
pendingMoves.push(msg);
// Call move without waiting for reply
canister.move(msg);
// Query move with pendingMoves
pendingMoves.push(msg);
const tmp = await canister.fakeMove(pendingMoves);
// Update playMessages for myself
playerMessages[myid] = pendingMoves;
// Send p2p msgs
const others = state.getOtherPlayers();
others.forEach(id => {
const conn = peer.connect(id);
conn.on('open', () => {
console.log("send", pendingMoves);
conn.send([myid, pendingMoves]);
//conn.send("hi");
});
});

// Query move with playerMessages
// construct candid format
const messages = [];
for (const id in playerMessages) {
const m = {
_0_: CanisterId.fromHex(id),
_1_: playerMessages[id]
};
messages.push(m);
}
const tmp = await canister.fakeMove(messages);
tmpState.update(tmp);
// Remove processed moves
pendingMoves = pendingMoves.filter(m => m.seq >= processedSeq);

await render();
e.preventDefault();
}


async function render() {
// Draw confirmed state
const res = await canister.getMap();
state.update(res);

const pending = myseq - processedSeq;
score.innerText = processedSeq.toString();
if (pending > 0)
score.innerText += " pending: " + pending.toString();
// receive p2p msgs
peer.on('connection', conn => {
conn.on('data', data => {
console.log("recv", data);
const [id, pending] = data;
playerMessages[id] = pending;
});
});
}

class Pos {
Expand Down Expand Up @@ -104,24 +137,37 @@ class Map {
} else
return ""
}
getOtherPlayers() {
const list = [];
for (const pos in this._grids) {
const person = this._grids[pos].person;
if (typeof person !== 'undefined') {
const id = idToPeerId(person);
if (id !== myid) {
list.push(id);
}
}
}
return list;
}
// update map and draw the diff
update(g) {
processedSeq = g[1];
const new_grids = [];
g[0].forEach(grid => {
const pos = Pos.fromPos(grid._0_);
new_grids[pos] = Map.getGridType(grid._1_);
new_grids[pos] = grid._1_;
});

for (const pos in this._grids) {
const type = this._grids[pos];
const type = Map.getGridType(this._grids[pos]);
grids[pos].classList.remove(type);
if (!this._isFinal) {
grids[pos].classList.remove("temp");
}
}
for (const pos in new_grids) {
const type = new_grids[pos];
const type = Map.getGridType(new_grids[pos]);
grids[pos].classList.add(type);
if (!this._isFinal) {
grids[pos].classList.add("temp");
Expand All @@ -143,11 +189,22 @@ let tmpState = new Map(false);
let myid;
let myseq;
let processedSeq;
let peer;
let playerMessages = [];

const score = document.createElement('div');
score.id = "maze_score";

async function init() {
function idToPeerId(principal) {
return principal.toText().slice(3, -2);
}

function init() {
const link = document.createElement('script');
link.setAttribute('src', 'https://cdn.jsdelivr.net/npm/peerjs@1.2.0/dist/peerjs.min.js');
link.setAttribute('type', 'text/javascript');
document.getElementsByTagName("head")[0].appendChild(link);

const container = document.createElement('div');
container.id = "maze_container";
const maze = document.createElement('div');
Expand All @@ -160,7 +217,7 @@ async function init() {

let div = document.createElement('div');
div.id = "maze_message";
document.body.appendChild(div);
document.body.appendChild(div);

document.addEventListener("keydown", mazeKeyPressHandler, false);

Expand All @@ -171,9 +228,18 @@ async function init() {
join.addEventListener('click', () => {
(async () => {
const res = await canister.join();
myid = res[0];
myid = idToPeerId(res[0]);
myseq = res[1].toNumber();
setInterval(render, 200);
// create p2p object
peer = new Peer(myid, { debug: 2 });
/*peer = new Peer(peerid, {
host: 'localhost',
port: 9000,
path: '/myapp',
debug: 2
});*/
// set timer
//setInterval(render, 200);
})();
});
}
Expand Down
1 change: 0 additions & 1 deletion src/maze_assets/maze.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
content: "\1F381";
}
#maze div.temp::after {
background-color: #45aa45;
opacity: 0.6;
}
#maze div.hero::after {
Expand Down