Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staging #3

Merged
merged 70 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
fcd7617
Update YourContract.sol
cacosta88 Oct 7, 2023
f34c79e
backend init
Avelous Oct 7, 2023
7f93283
backend init
Avelous Oct 7, 2023
c57858f
Update YourContract.sol
cacosta88 Oct 8, 2023
f7945aa
Merge pull request #1 from cacosta88/staging
ZakGriffith Oct 9, 2023
43c1ce1
dice demo init setup
Avelous Oct 16, 2023
549b17b
live setup
Avelous Oct 16, 2023
0d2eaa5
sepolia chain
Avelous Oct 17, 2023
c7f726e
cleanup
Avelous Oct 17, 2023
f78ade2
sever config
Avelous Oct 17, 2023
cf5d24e
Update localUrl to 6001
portdeveloper Oct 17, 2023
4ee9129
Fix privateKey being undefined
portdeveloper Oct 17, 2023
cad37e6
Merge pull request #1 from portdeveloper/av-demo
Avelous Oct 17, 2023
bf54458
added player and admin roles, ui updates and admin functions
Avelous Oct 23, 2023
f76b19a
styling updates
Avelous Oct 23, 2023
628b2af
styling updates and added simple description
Avelous Oct 23, 2023
bcd4482
sockets-io package
Avelous Oct 23, 2023
745ac01
added admin routes
Avelous Oct 23, 2023
3b980e9
functions update and added sockets for realtime event handling
Avelous Oct 23, 2023
dc542ed
live server
Avelous Oct 23, 2023
a57a9b2
validate function fix
Avelous Oct 23, 2023
00aebb3
fixed menu style
Avelous Oct 23, 2023
90a78b7
sepolia network
Avelous Oct 23, 2023
f17ddfe
Merge branch 'av-demo' into av-demo-live
Avelous Oct 23, 2023
883ec49
server cors config
Avelous Oct 23, 2023
3b37599
Merge branch 'av-demo' into av-demo-live
Avelous Oct 23, 2023
1182fa5
menu button ui
Avelous Oct 23, 2023
c32d897
menu button ui
Avelous Oct 23, 2023
a9bca2a
menu button ui
Avelous Oct 23, 2023
e188bb3
host text
Avelous Oct 23, 2023
78144d0
websockets configuration with ably
Avelous Oct 24, 2023
bd803bb
websockets configuration and ui updates
Avelous Oct 24, 2023
e672dc0
page width update
Avelous Oct 24, 2023
e6457f7
Added a gr scanner and fixed game fetching error
Avelous Nov 10, 2023
79875c9
merged av-demo
Avelous Nov 10, 2023
99ee454
fixed type errors
Avelous Nov 10, 2023
fc14856
Merge branch 'av-demo' into av-demo-live
Avelous Nov 10, 2023
27a1934
rectified websockets connections
Avelous Nov 10, 2023
7f03c7a
Merge branch 'av-demo' into av-demo-live
Avelous Nov 10, 2023
463aa77
Added notifications on api calls, added condolence message and invite…
Avelous Nov 14, 2023
f1456a0
reduced the size of wallet modal buttons, added a spinner for joing a…
Avelous Nov 14, 2023
edc6b02
changed header title
Avelous Nov 14, 2023
e35ae65
fixed invite url error
Avelous Nov 14, 2023
6ae15ed
disabled videoref loop
Avelous Nov 14, 2023
344ece8
updated video timeout
Avelous Nov 14, 2023
d836ca9
updated dice video and added price component
Avelous Nov 14, 2023
f01d014
updated env
Avelous Nov 14, 2023
426fd16
backend env update
Avelous Nov 14, 2023
4b20fe6
matic chain
Avelous Nov 14, 2023
f70f22c
deploying to optimism
Avelous Nov 15, 2023
33aff60
set etherinput button type
Avelous Nov 15, 2023
ecb1e08
edited front page text
Avelous Nov 15, 2023
0311cb9
Changed site title
Avelous Nov 15, 2023
401760d
Updated next version
Avelous Nov 15, 2023
ffa1415
Added 1 seconds delay to progressively roll the dice
Avelous Nov 16, 2023
9e6316b
testing video on live url
Avelous Nov 16, 2023
80a131f
testing video on live url
Avelous Nov 16, 2023
83bc6b0
testing video on live url
Avelous Nov 16, 2023
e09a8dc
testing video on live url
Avelous Nov 16, 2023
1d473bb
testing video on live url
Avelous Nov 16, 2023
009735a
testing video on live url
Avelous Nov 16, 2023
9fadb93
testing video on live url
Avelous Nov 16, 2023
d22584c
testing video on live url
Avelous Nov 16, 2023
377e41f
testing video on live url
Avelous Nov 16, 2023
41f988f
testing video on live url
Avelous Nov 16, 2023
af02a2b
testing video on live url
Avelous Nov 16, 2023
309862b
testing video on live url
Avelous Nov 16, 2023
413bd1d
testing video on live url
Avelous Nov 16, 2023
01f3e00
set .env path for backend
Avelous Feb 8, 2024
d708e7f
Merge pull request #2 from Avelous/master
ZakGriffith Feb 8, 2024
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
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn lint-staged --verbose
# yarn lint-staged --verbose
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"workspaces": {
"packages": [
"packages/hardhat",
"packages/nextjs"
"packages/nextjs",
"packages/backend"
]
},
"scripts": {
Expand All @@ -27,7 +28,8 @@
"postinstall": "husky install",
"precommit": "lint-staged",
"vercel": "yarn workspace @se-2/nextjs vercel",
"vercel:yolo": "yarn workspace @se-2/nextjs vercel:yolo"
"vercel:yolo": "yarn workspace @se-2/nextjs vercel:yolo",
"backend": "yarn workspace @se-2/backend backend"
},
"packageManager": "[email protected]",
"devDependencies": {
Expand Down
Empty file added packages/backend/.env.example
Empty file.
4 changes: 4 additions & 0 deletions packages/backend/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# folders
node_modules/
# files
**/*.json
17 changes: 17 additions & 0 deletions packages/backend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"env": {
"node": true
},
"parser": "@typescript-eslint/parser",
"extends": ["plugin:prettier/recommended", "plugin:@typescript-eslint/recommended"],
"rules": {
"@typescript-eslint/no-unused-vars": ["error"],
"@typescript-eslint/no-explicit-any": ["off"],
"prettier/prettier": [
"warn",
{
"endOfLine": "auto"
}
]
}
}
9 changes: 9 additions & 0 deletions packages/backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules
.env
coverage
coverage.json
typechain
typechain-types
temp


19 changes: 19 additions & 0 deletions packages/backend/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"arrowParens": "avoid",
"printWidth": 120,
"tabWidth": 2,
"trailingComma": "all",
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 80,
"tabWidth": 4,
"useTabs": true,
"singleQuote": false,
"bracketSpacing": true,
"explicitTypes": "always"
}
}
]
}
3 changes: 3 additions & 0 deletions packages/backend/backend.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const JWT_SECRET = "superhardstring";
export const PORT = 4001;
export const KEY = "";
239 changes: 239 additions & 0 deletions packages/backend/controllers/Admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
import Game from "../models/Game";
import Invites from "../models/Invites";
import bcrypt from "bcrypt";
import { Request, Response } from "express";
import jwt from "jsonwebtoken";
import { JWT_SECRET } from "../backend.config";
import { ably } from "..";

async function generateUniqueInvite(length: number) {
let invites = await Invites.findOne();

if (!invites) {
const newInvites = new Invites({
codes: [],
});
invites = await newInvites.save();
}

const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
let invite = "";
const existingCodes = invites?.codes || [];

while (true) {
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
invite += characters.charAt(randomIndex);
}

if (!existingCodes.includes(invite)) {
existingCodes.push(invite);
await Invites.findByIdAndUpdate(invites?.id, {
codes: existingCodes,
});
return invite;
}

invite = "";
}
}

export const createGame = async (req: Request, res: Response) => {
try {
const { maxPlayers, diceCount, hiddenChars, privateKey, prize, mode, adminAddress } = req.body;

const salt = await bcrypt.genSalt();
// const privateKeyHash = await bcrypt.hash(privateKey, salt);

const newGame = new Game({
adminAddress,
status: "ongoing",
inviteCode: await generateUniqueInvite(8),
maxPlayers,
diceCount,
mode,
privateKey,
hiddenChars,
prize,
});

let token;

if (JWT_SECRET) token = jwt.sign({ address: adminAddress }, JWT_SECRET);

const savedGame = await newGame.save();
res.status(201).json({ token, game: savedGame });
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
};

export const pauseGame = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const game = await Game.findById(id);

if (!game) {
return res.status(404).json({ error: "Game not found." });
}

if (game.status !== "ongoing") {
return res.status(400).json({ error: "Game is not ongoing." });
}

// Update game status to "paused"
game.status = "paused";
const updatedGame = await game.save();

const channel = ably.channels.get(`gameUpdate`);
channel.publish(`gameUpdate`, updatedGame);
res.status(200).json(updatedGame);
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
};

export const resumeGame = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const game = await Game.findById(id);

if (!game) {
return res.status(404).json({ error: "Game not found." });
}

if (game.status === "finished") {
return res.status(400).json({ error: "Game has ended." });
}

if (game.status !== "paused") {
return res.status(400).json({ error: "Game is not paused." });
}

// Update game status to "ongoing"
game.status = "ongoing";
const updatedGame = await game.save();

const channel = ably.channels.get(`gameUpdate`);
channel.publish(`gameUpdate`, updatedGame);
res.status(200).json(updatedGame);
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
};

export const endGame = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const game = await Game.findById(id);

if (!game) {
return res.status(404).json({ error: "Game not found." });
}

if (game.status === "finished") {
return res.status(400).json({ error: "Game is already finished." });
}

// Update game status to "finished"
game.status = "finished";
if (req.body) {
const { winner } = req.body;
game.winner = winner;
}
const updatedGame = await game.save();

const channel = ably.channels.get(`gameUpdate`);
channel.publish(`gameUpdate`, updatedGame);

res.status(200).json(updatedGame);
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
};

export const changeGameMode = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const { mode } = req.body;

const game = await Game.findById(id);

if (!game) {
return res.status(404).json({ error: "Game not found." });
}

// if (game.status !== "paused") {
// return res.status(400).json({ error: "Game is not paused." });
// }

if (mode !== "auto" && mode !== "manual") {
return res.status(400).json({ error: "Invalid game mode." });
}

game.mode = mode;

const updatedGame = await game.save();

const channel = ably.channels.get(`gameUpdate`);
channel.publish(`gameUpdate`, updatedGame);

res.status(200).json(updatedGame);
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
};

export const changePrize = async (req: Request, res: Response) => {
try {
const { gameId } = req.params;
const { newPrize } = req.body;

const game = await Game.findById(gameId);

if (!game) {
return res.status(404).json({ error: "Game not found." });
}

if (game.status !== "ongoing") {
return res.status(400).json({ error: "Game is not ongoing." });
}

game.prize = newPrize;
const updatedGame = await game.save();

res.status(200).json(updatedGame);
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
};

export const kickPlayer = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const { playerAddress } = req.body;
const game = await Game.findById(id);

if (!game) {
return res.status(404).json({ error: "Game not found." });
}

if (game.status !== "ongoing") {
return res.status(400).json({ error: "Game is not ongoing." });
}

const playerIndex = game.players.indexOf(playerAddress);
if (playerIndex === -1) {
return res.status(404).json({ error: "Player not found in the game." });
}

game.players.splice(playerIndex, 1);
const updatedGame = await game.save();
const channel = ably.channels.get(`gameUpdate`);
channel.publish(`gameUpdate`, updatedGame);

res.status(200).json(updatedGame);
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
};
47 changes: 47 additions & 0 deletions packages/backend/controllers/Player.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Game from "../models/Game";
import { Response, Request } from "express";
import jwt from "jsonwebtoken";
import { ably } from "..";

const JWT_SECRET = process.env.JWT_SECRET || "superhardstring";

export const join = async (req: Request, res: Response) => {
try {
const { inviteCode, playerAddress } = req.body;
const game = await Game.findOne({ inviteCode });

if (!game) {
return res.status(404).json({ error: "Game not found." });
}

if (game.status !== "ongoing") {
return res.status(400).json({ error: "Game is not ongoing." });
}

if (game.players.length >= game.maxPlayers) {
return res.status(400).json({ error: "Game is full." });
}

if (game.players.includes(playerAddress)) {
return res.status(200).json(game); // Player is already in the game
}

let token;

if (JWT_SECRET) token = jwt.sign({ address: playerAddress }, JWT_SECRET);

game.players.push(playerAddress);
const savedGame = await game.save();

const channel = ably.channels.get(`gameUpdate`);
channel.publish(`gameUpdate`, savedGame);
res.status(200).json({ token, game: savedGame });
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
};

export const leave = () => {};

export const sweepPrize = () => {};
export const markSlotsAsFoundPerPlayer = () => {};
Loading
Loading