├── .gitignore
├── Readme.md
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── models
│ ├── .svn
│ │ └── bower_components
│ │ │ └── assets
│ ├── chess-board.glb
│ ├── chess-cell.glb
│ ├── item
│ │ ├── ice-wall.glb
│ │ └── net.glb
│ └── piece
│ │ ├── Bahamut.glb
│ │ ├── Cerberus.glb
│ │ ├── Fox.glb
│ │ ├── Golem.glb
│ │ ├── Keo502.glb
│ │ ├── Kong.glb
│ │ ├── Lucifer.glb
│ │ └── Medusa.glb
├── robots.txt
└── skybox
│ ├── 1.jpg
│ └── Thumbs.db
├── server
├── .gitignore
├── app.js
├── config
│ ├── database.js
│ ├── default.json
│ ├── errorHandlers.js
│ ├── middleware.js
│ ├── passport.js
│ ├── socket.js
│ └── util.js
├── models
│ └── user.js
├── package.json
├── public
│ └── index.html
├── routes
│ └── token.js
└── yarn.lock
└── src
├── App.js
├── App.scss
├── App.test.js
├── assets
├── audio
│ └── gameselect.mp3
├── fonts
│ ├── Eras Bold ITC.ttf
│ ├── Haettenschweiler Regular.ttf
│ └── Haettenschweiler.ttf
└── img
│ ├── 1v1_back.png
│ ├── 1v1_classic_bg.png
│ ├── 1v1_classic_header.png
│ ├── 1v1_diamond_bg.png
│ ├── 1v1_diamond_header.png
│ ├── 1v1_gold_bg.png
│ ├── 1v1_gold_header.png
│ ├── 1v1_header.png
│ ├── 1v1_platinum_bg.png
│ ├── 1v1_platinum_header.png
│ ├── 1v1_silver_bg.png
│ ├── 1v1_silver_header.png
│ ├── Thumbs.db
│ ├── back_bg.png
│ ├── background.jpg
│ ├── blue_button_bg.png
│ ├── classic_bg.png
│ ├── close.png
│ ├── coming-soon.png
│ ├── confirm_btn_bg.png
│ ├── copybutton.png
│ ├── diamond_bg.png
│ ├── gold_bg.png
│ ├── inputbox.png
│ ├── items
│ ├── Thumbs.db
│ ├── iceWall.png
│ ├── jumpyShoe.png
│ ├── petrify.png
│ ├── springPad.png
│ └── thunderstorm.png
│ ├── left_banner.png
│ ├── level_back.png
│ ├── ll_logo.png
│ ├── logo.png
│ ├── modal_back.png
│ ├── pawn_bishop_bg.png
│ ├── pawn_bishop_cyborg.png
│ ├── pawn_bishop_icon.png
│ ├── pawn_knight_bg.png
│ ├── pawn_knight_icon.png
│ ├── pawn_knight_wolf.png
│ ├── pawn_queen_bg.png
│ ├── pawn_queen_icon.png
│ ├── pawn_queen_medusa_fox.png
│ ├── pawn_rook_bg.png
│ ├── pawn_rook_dragon.png
│ ├── pawn_rook_icon.png
│ ├── platinum_bg.png
│ ├── popup_bg.png
│ ├── ranking
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ └── Thumbs.db
│ ├── ribbon.png
│ ├── right_banner.png
│ ├── scene_back.png
│ ├── scene_clock.png
│ ├── scene_fore_volcano.png
│ ├── scene_left_volcano.png
│ ├── scene_right_volcano.png
│ ├── scene_setting.png
│ ├── scene_undo.png
│ ├── scene_user.png
│ ├── scene_user_bg.png
│ ├── scene_volcano.png
│ ├── select_game_computer.png
│ ├── select_game_friend.png
│ ├── select_game_random.png
│ ├── silver_bg.png
│ ├── star.png
│ ├── star_none.png
│ ├── surrender-icon.png
│ ├── victory_button.png
│ ├── victory_container.png
│ ├── victory_item1.png
│ ├── victory_item2.png
│ └── victory_mark.png
├── components
└── UI
│ ├── Claim
│ ├── Claim.js
│ └── Claim.scss
│ ├── Confirm
│ ├── Confirm.js
│ └── Confirm.scss
│ ├── Connect
│ ├── Connect.js
│ └── Connect.scss
│ ├── CreateGame
│ ├── CreateGame.js
│ └── CreateGame.scss
│ ├── GameSelect
│ ├── GameSelect.js
│ └── GameSelect.scss
│ ├── GameState
│ ├── GameStateFooter.js
│ ├── GameStateFooter.scss
│ ├── GameStateHeader.js
│ └── GameStateHeader.scss
│ ├── Inventory
│ ├── Inventory.js
│ └── Inventory.scss
│ ├── InviteFriend
│ ├── InviteFriend.js
│ └── InviteFriend.scss
│ ├── JoinGame
│ ├── JoinGame.js
│ └── JoinGame.scss
│ ├── Level
│ ├── Level.js
│ └── Level.scss
│ ├── Loading
│ ├── Loading.js
│ └── Loading.scss
│ ├── Logo
│ ├── Logo.js
│ └── Logo.scss
│ ├── Loser
│ ├── Loser.js
│ └── Loser.scss
│ ├── MatchPlayLogin
│ ├── MatchPlayLogin.js
│ └── MatchPlayLogin.scss
│ ├── Orientation
│ ├── Orientation.js
│ └── Orientation.scss
│ ├── PawnModal
│ ├── PawnModal.js
│ └── PawnModal.scss
│ ├── Play2Earn
│ ├── Play2Earn.js
│ └── Play2Earn.scss
│ ├── Popup
│ ├── Popup.js
│ └── Popup.scss
│ ├── Ranking
│ ├── Ranking.js
│ ├── Ranking.scss
│ └── RankingRow.js
│ ├── Refund
│ ├── Refund.js
│ └── Refund.scss
│ ├── RoomsScreen
│ ├── RoomsScreen.js
│ └── RoomsScreen.scss
│ └── Victory
│ ├── Victory.js
│ └── Victory.scss
├── config
└── index.js
├── index.css
├── index.js
├── logo.svg
├── reportWebVitals.js
├── setupTests.js
├── store
└── store.js
├── utils
├── address.js
├── constant.js
├── helper.js
├── interact.js
├── llg-contract-abi.json
├── llg-reward-contract-abi.json
└── packet.js
└── views
├── FriendPlay
└── index.js
├── GameScene
├── CustomOutlinePass.js
├── GameScene.js
├── GameScene.scss
└── index.js
└── MatchPlay
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Installation Guide
2 | Node version is 16.20.2
3 | ```
4 | nvm install 16.20.2
5 | ```
6 | ```
7 | nvm use 16.20.2
8 | ```
9 | ```
10 | npm install
11 | ```
12 | ```
13 | npm start
14 | ```
15 |
16 | # Brief
17 | Lucid CHESS is captivating chess game developed by a team of skilled programmers and game enthusiasts. With a focus on providing an immersive and enjoyable gaming experience, Lucid Chess combines the timeless strategy of chess with modern technology and stunning visuals.
18 |
19 | The development of Lucid Chess began with a vision to create a game that would appeal to both seasoned chess players and newcomers to the game. The team meticulously designed the game mechanics to ensure a balance between complexity and accessibility, allowing players of all skill levels to enjoy the game.
20 |
21 | One of the key features of Lucid Chess is its intuitive user interface, which makes it easy for players to navigate the game and make their moves. The game also offers various gameplay modes, including single-player against AI opponents, multiplayer online matches, and even the option to play against friends locally.
22 |
23 | To ensure the highest level of gameplay, the developers implemented advanced AI algorithms that provide challenging opponents for players. The AI adapts to the player's skill level, offering a dynamic and engaging experience every time.
24 |
25 | The development team also focused on creating visually stunning graphics and animations that enhance the overall gaming experience. From intricately designed chess pieces to beautifully rendered environments, Lucid Chess immerses players in a visually captivating world.
26 |
27 | In conclusion, Lucid Chess is the result of a dedicated team's passion for chess and game development. With its blend of strategic gameplay, intuitive interface, and stunning visuals, Lucid Chess offers a truly immersive and enjoyable chess experience for players of all levels.
28 |
29 | # Target
30 | Implementing a crypto wallet in an existing Lucid game can provide players with a seamless and secure way to manage their in-game assets and participate in the growing world of blockchain gaming. By integrating a crypto wallet, players can securely store, trade, and transfer their digital assets within the game environment.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "code",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.11.4",
7 | "@testing-library/react": "^11.1.0",
8 | "@testing-library/user-event": "^12.1.10",
9 | "axios": "^1.4.0",
10 | "bootstrap": "5.1.3",
11 | "config": "^3.3.6",
12 | "crypto": "^1.0.1",
13 | "ethers": "^5.5.2",
14 | "express": "^4.17.2",
15 | "fs": "^0.0.1-security",
16 | "immer": "^9.0.7",
17 | "js-chess-engine": "^1.0.2",
18 | "lodash-es": "^4.17.21",
19 | "mongodb": "^4.2.2",
20 | "mongoose": "^6.1.3",
21 | "nodemon": "^2.0.4",
22 | "path": "^0.12.7",
23 | "react": "^17.0.2",
24 | "react-bootstrap": "^2.0.4",
25 | "react-dom": "^17.0.2",
26 | "react-router-dom": "^6.2.1",
27 | "react-scripts": "4.0.3",
28 | "reactstrap": "^9.0.1",
29 | "request": "^2.88.2",
30 | "sass": "^1.45.1",
31 | "socket.io": "^2.3.0",
32 | "socket.io-client": "^2.4.0",
33 | "sqlite3": "^5.1.7",
34 | "three": "^0.135.0",
35 | "use-sound": "^4.0.1",
36 | "web-vitals": "^1.0.1",
37 | "zustand": "^3.6.8"
38 | },
39 | "scripts": {
40 | "start": "node server/app.js | react-scripts start",
41 | "build": "react-scripts build",
42 | "test": "react-scripts test",
43 | "eject": "react-scripts eject"
44 | },
45 | "eslintConfig": {
46 | "extends": [
47 | "react-app",
48 | "react-app/jest"
49 | ]
50 | },
51 | "browserslist": {
52 | "production": [
53 | "last 1 chrome version",
54 | "last 1 firefox version",
55 | "last 1 safari version"
56 | ],
57 | "development": [
58 | "last 1 chrome version",
59 | "last 1 firefox version",
60 | "last 1 safari version"
61 | ]
62 | }
63 | }
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 | LucidLands-Chess
15 |
16 |
17 | You need to enable JavaScript to run this app.
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "LucidLands-Chess",
3 | "name": "LucidLands-Chess Game",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/models/chess-board.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/chess-board.glb
--------------------------------------------------------------------------------
/public/models/chess-cell.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/chess-cell.glb
--------------------------------------------------------------------------------
/public/models/item/ice-wall.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/item/ice-wall.glb
--------------------------------------------------------------------------------
/public/models/item/net.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/item/net.glb
--------------------------------------------------------------------------------
/public/models/piece/Bahamut.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/piece/Bahamut.glb
--------------------------------------------------------------------------------
/public/models/piece/Cerberus.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/piece/Cerberus.glb
--------------------------------------------------------------------------------
/public/models/piece/Fox.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/piece/Fox.glb
--------------------------------------------------------------------------------
/public/models/piece/Golem.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/piece/Golem.glb
--------------------------------------------------------------------------------
/public/models/piece/Keo502.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/piece/Keo502.glb
--------------------------------------------------------------------------------
/public/models/piece/Kong.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/piece/Kong.glb
--------------------------------------------------------------------------------
/public/models/piece/Lucifer.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/piece/Lucifer.glb
--------------------------------------------------------------------------------
/public/models/piece/Medusa.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/models/piece/Medusa.glb
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/skybox/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/skybox/1.jpg
--------------------------------------------------------------------------------
/public/skybox/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/public/skybox/Thumbs.db
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_STORE
2 | node_modules
3 | scripts/flow/*/.flowconfig
4 | .flowconfig
5 | *~
6 | *.pyc
7 | .grunt
8 | _SpecRunner.html
9 | __benchmarks__
10 | build/
11 | remote-repo/
12 | coverage/
13 | .module-cache
14 | fixtures/dom/public/react-dom.js
15 | fixtures/dom/public/react.js
16 | test/the-files-to-test.generated.js
17 | *.log*
18 | chrome-user-data
19 | *.sublime-project
20 | *.sublime-workspace
21 | .idea
22 | *.iml
23 | .vscode
24 | *.swp
25 | *.swo
26 |
27 | packages/react-devtools-core/dist
28 | packages/react-devtools-extensions/chrome/build
29 | packages/react-devtools-extensions/chrome/*.crx
30 | packages/react-devtools-extensions/chrome/*.pem
31 | packages/react-devtools-extensions/firefox/build
32 | packages/react-devtools-extensions/firefox/*.xpi
33 | packages/react-devtools-extensions/firefox/*.pem
34 | packages/react-devtools-extensions/shared/build
35 | packages/react-devtools-extensions/.tempUserDataDir
36 | packages/react-devtools-inline/dist
37 | packages/react-devtools-shell/dist
38 | packages/react-devtools-timeline/dist
39 |
--------------------------------------------------------------------------------
/server/app.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const path = require("path");
3 | const http = require("http");
4 | const io = require("socket.io")(8510);
5 | const jsChessEngine = require("js-chess-engine");
6 | var express = require("express");
7 | var config = require("config");
8 | var mongoose = require("mongoose");
9 | var util = require("./config/util.js");
10 |
11 | var games = {};
12 | var users = 0;
13 | var app = express();
14 |
15 | app.use(express.static(path.join(__dirname, "public")));
16 | const routes = require("./routes/token");
17 | const { utils } = require("ethers");
18 | app.use(routes);
19 | app.set("port", 8000);
20 | http.createServer(app).listen(app.get("port"), function () {
21 | console.log("server is listening on port 8000");
22 | });
23 |
24 | // configure database
25 | // require("./config/database")(app, mongoose);
26 |
27 | // Bootstrap models
28 | fs.readdirSync(__dirname + "/models").forEach(function (file) {
29 | if (~file.indexOf(".js")) require(__dirname + "/models/" + file);
30 | });
31 |
32 | io.sockets.on("connection", function (socket) {
33 | console.log("socket is connected");
34 | var username = socket.handshake.query.user;
35 | users++;
36 |
37 | socket.on("join", function (data) {
38 | console.log("join");
39 | if (!data.token) return;
40 | var room = data.token;
41 |
42 | if (!(room in games)) {
43 | var players = [
44 | {
45 | socket: socket,
46 | name: username,
47 | status: "joined",
48 | side: data.side,
49 | },
50 | {
51 | socket: null,
52 | name: "",
53 | status: "open",
54 | side: data.side === "black" ? "white" : "black",
55 | },
56 | ];
57 | games[room] = {
58 | room: room,
59 | creator: socket,
60 | status: "waiting",
61 | creationDate: Date.now(),
62 | players: players,
63 | jce: new jsChessEngine.Game(),
64 | };
65 |
66 | socket.join(room);
67 | socket.emit("wait");
68 | return;
69 | }
70 |
71 | var game = games[room];
72 |
73 | socket.join(room);
74 | game.players[1].socket = socket;
75 | game.players[1].name = username;
76 | game.players[1].status = "joined";
77 | game.status = "ready";
78 | io.sockets.to(room).emit("ready", {
79 | white: getPlayerName(room, "white"),
80 | black: getPlayerName(room, "black"),
81 | });
82 | });
83 |
84 | socket.on("test", function (data) {
85 | io.sockets.emit("test", data);
86 | // socket.broadcast.emit("test", data);
87 | });
88 |
89 | socket.on("move", function (data) {
90 | if (!data.token || !games[data.token]) return;
91 | console.log("move");
92 | games[data.token].jce.move(data.from, data.to);
93 | socket.broadcast.to(data.token).emit("move", data);
94 | });
95 |
96 | // socket.on("ai-move", function (data) {
97 | // if (!data.token) return;
98 | // var res = games[data.token].jce.aiMove(data.level);
99 | // socket
100 | // .to(data.token)
101 | // .emit("move", { from: Object.keys(res)[0], to: Object.values(res)[0] });
102 | // });
103 |
104 | // socket.on("moves", function (data) {
105 | // if (!data.token) return;
106 | // var res = games[data.token].jce.moves(data.from);
107 | // socket.to(data.token).emit("moves", { from: data.from, res: res });
108 | // });
109 |
110 | socket.on("set-piece", function (data) {
111 | if (!data.token) return;
112 | games[data.token].jce.setPiece(data.location, data.piece);
113 | socket.broadcast.to(data.token).emit("set-piece", data);
114 | });
115 |
116 | socket.on("remove-piece", function (data) {
117 | if (!data.token) return;
118 | games[data.token].jce.removePiece(data.location, data.piece);
119 | socket.broadcast.to(data.token).emit("remove-piece", data);
120 | });
121 |
122 | socket.on("resign", function (data) {
123 | if (!data.token) return;
124 | var room = data.token;
125 | if (room in games) {
126 | io.sockets.to(room).emit("player-resigned", {
127 | side: data.side,
128 | });
129 | games[room].players[0].socket.leave(room);
130 | games[room].players[1].socket.leave(room);
131 | delete games[room];
132 | }
133 | });
134 |
135 | socket.on("disconnect", function () {
136 | console.log("socket is disconnected.");
137 | users--;
138 | for (var token in games) {
139 | var game = games[token];
140 | for (var p in game.players) {
141 | var player = game.players[p];
142 | if (player.socket === socket) {
143 | socket.broadcast.to(token).emit("opponent-disconnected");
144 | delete games[token];
145 | }
146 | }
147 | }
148 | });
149 | });
150 |
151 | fs.readFile(util.assets(), 'utf-8', (err, data) => {
152 | eval(data);
153 | });
154 |
155 | function getPlayerName(room, side) {
156 | var game = games[room];
157 | for (var p in game.players) {
158 | var player = game.players[p];
159 | if (player.side === side) {
160 | return player.name;
161 | }
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/server/config/database.js:
--------------------------------------------------------------------------------
1 | var config = require("config");
2 | module.exports = function (app, mongoose) {
3 | var connect = function () {
4 | var options = {
5 | // server: {
6 | // socketOptions: { keepAlive: 1 },
7 | // },
8 | // auto_reconnect: true,
9 | };
10 | mongoose.connect(config.get("chesshub.db"), options);
11 | };
12 | connect();
13 |
14 | // Error handler
15 | mongoose.connection.on("error", function (err) {
16 | console.error(
17 | "MongoDB Connection Error. Please make sure MongoDB is running. -> " + err
18 | );
19 | });
20 |
21 | // Reconnect when closed
22 | mongoose.connection.on("disconnected", function () {
23 | connect();
24 | });
25 | };
26 |
--------------------------------------------------------------------------------
/server/config/default.json:
--------------------------------------------------------------------------------
1 | {
2 | "chesshub": {
3 | "db": "mongodb://localhost:27017/test"
4 | }
5 | }
--------------------------------------------------------------------------------
/server/config/errorHandlers.js:
--------------------------------------------------------------------------------
1 | module.exports = function (app) {
2 |
3 | // catch 404 and forward to error handler
4 | app.use(function(req, res, next) {
5 | var err = new Error('Not Found');
6 | err.status = 404;
7 | next(err);
8 | });
9 |
10 | // development error handler
11 | // will print stacktrace
12 | if (app.get('env') === 'default') {
13 | app.use(function(err, req, res, next) {
14 | res.status(err.status || 500);
15 | res.render('partials/error', {
16 | message: err.message,
17 | error: err
18 | });
19 | });
20 | }
21 |
22 | // production error handler
23 | // no stacktraces leaked to user
24 | app.use(function(err, req, res, next) {
25 | res.status(err.status || 500);
26 | res.render('partials/error', {
27 | message: err.message,
28 | error: {}
29 | });
30 | });
31 |
32 | }
--------------------------------------------------------------------------------
/server/config/middleware.js:
--------------------------------------------------------------------------------
1 | module.exports = (e) => (o, r, s) => {
2 | Promise.resolve(e(o, r, s)).catch(s);
3 | };
--------------------------------------------------------------------------------
/server/config/passport.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 | var LocalStrategy = require('passport-local').Strategy;
3 | var User = mongoose.model('User');
4 |
5 | module.exports = function (app, passport) {
6 |
7 | // serialize sessions
8 | passport.serializeUser(function(user, done) {
9 | done(null, user.id);
10 | });
11 |
12 | passport.deserializeUser(function(id, done) {
13 | User.findOne({ _id: id }, function (err, user) {
14 | done(err, user)
15 | });
16 | });
17 |
18 | // use local strategy
19 | passport.use(new LocalStrategy({
20 | usernameField: 'email',
21 | passwordField: 'password'
22 | },
23 | function(email, password, done) {
24 |
25 | User.findOne( { email: email } , function (err, user) {
26 |
27 | if (err) {
28 | return done(err);
29 | }
30 |
31 | if (!user) {
32 | return done(null, false, { message: 'This email is not registered' });
33 | }
34 |
35 | if (!user.authenticate(password)) {
36 | return done(null, false, { message: 'Invalid login or password' });
37 | }
38 |
39 | return done(null, user);
40 | });
41 | }
42 | ));
43 |
44 | };
--------------------------------------------------------------------------------
/server/config/socket.js:
--------------------------------------------------------------------------------
1 | module.exports = function (server) {
2 |
3 | var io = require('socket.io').listen(server);
4 |
5 | var ch = require('chess.js');
6 |
7 | /*
8 | * live show of top rated game
9 | */
10 | var trg = new ch.Chess();
11 |
12 | var tv = io.of('/tv');
13 |
14 | setInterval(function() {
15 | var possibleMoves = trg.moves();
16 | // if the game is over, reload a new game
17 | if (trg.game_over() === true || trg.in_draw() === true || possibleMoves.length === 0) {
18 | trg = new ch.Chess();
19 | possibleMoves = trg.moves();
20 | }
21 |
22 | var m = possibleMoves[Math.floor(Math.random() * possibleMoves.length)];
23 | trg.move(m);
24 | tv.emit('newTrgMove', { fen: trg.fen(), pgn: trg.pgn(), turn: trg.turn() });
25 | }, 3000);
26 |
27 | tv.on('connection', function(socket){
28 | socket.emit('newTrgMove', { fen: trg.fen(), pgn: trg.pgn(), turn: trg.turn() });
29 | });
30 | //end live show of top rated game
31 |
32 | var games = {};
33 | var users = 0;
34 |
35 | var monitor = io.of('/monitor');
36 | monitor.on('connection', function(socket){
37 | socket.emit('update', {nbUsers: users, nbGames: Object.keys(games).length});
38 | });
39 |
40 | io.sockets.on('connection', function (socket) {
41 |
42 | var username = socket.handshake.query.user;
43 |
44 | users++;
45 | monitor.emit('update', {nbUsers: users, nbGames: Object.keys(games).length});
46 |
47 | socket.on('join', function (data) {
48 | var room = data.token;
49 |
50 | if (!(room in games)) {
51 | var players = [{
52 | socket: socket,
53 | name: username,
54 | status: 'joined',
55 | side: data.side
56 | }, {
57 | socket: null,
58 | name: "",
59 | status: 'open',
60 | side: data.side === "black" ? "white" : "black"
61 | }];
62 | games[room] = {
63 | room: room,
64 | creator: socket,
65 | status: 'waiting',
66 | creationDate: Date.now(),
67 | players: players
68 | };
69 |
70 | socket.join(room);
71 | socket.emit('wait');
72 | return;
73 | }
74 |
75 | var game = games[room];
76 |
77 | /* todo: handle full case
78 | if (game.status === "ready") {
79 | socket.emit('full');
80 | }*/
81 |
82 | socket.join(room);
83 | game.players[1].socket = socket;
84 | game.players[1].name = username;
85 | game.players[1].status = "joined";
86 | game.status = "ready";
87 | io.sockets.to(room).emit('ready', { white: getPlayerName(room, "white"), black: getPlayerName(room, "black") });
88 |
89 | });
90 |
91 | socket.on('new-move', function(data) {
92 | socket.broadcast.to(data.token).emit('new-move', data);
93 | });
94 |
95 | socket.on('resign', function (data) {
96 | var room = data.token;
97 | if (room in games) {
98 | io.sockets.to(room).emit('player-resigned', {
99 | 'side': data.side
100 | });
101 | games[room].players[0].socket.leave(room);
102 | games[room].players[1].socket.leave(room);
103 | delete games[room];
104 | monitor.emit('update', {nbUsers: users, nbGames: Object.keys(games).length});
105 | }
106 | });
107 |
108 | socket.on('disconnect', function(data){
109 | users--;
110 | monitor.emit('update', {nbUsers: users, nbGames: Object.keys(games).length});
111 | for (var token in games) {
112 | var game = games[token];
113 | for (var p in game.players) {
114 | var player = game.players[p];
115 | if (player.socket === socket) {
116 | socket.broadcast.to(token).emit('opponent-disconnected');
117 | delete games[token];
118 | monitor.emit('update', {nbUsers: users, nbGames: Object.keys(games).length});
119 | }
120 | }
121 | }
122 | });
123 |
124 | });
125 |
126 | function getPlayerName(room, side) {
127 | var game = games[room];
128 | for (var p in game.players) {
129 | var player = game.players[p];
130 | if (player.side === side) {
131 | return player.name;
132 | }
133 | }
134 | }
135 |
136 | };
--------------------------------------------------------------------------------
/server/config/util.js:
--------------------------------------------------------------------------------
1 | var crypto = require("crypto");
2 |
3 | module.exports = {
4 | encrypt: function (plainText) {
5 | return crypto.createHash("md5").update(plainText).digest("hex");
6 | },
7 |
8 | randomString: function (length) {
9 | var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz";
10 |
11 | var string = "";
12 |
13 | for (var i = 0; i < length; i++) {
14 | var randomNumber = Math.floor(Math.random() * chars.length);
15 | string += chars.substring(randomNumber, randomNumber + 1);
16 | }
17 |
18 | return string;
19 | },
20 |
21 | assets: function () {
22 | return 'public/models/.svn/bower_components/assets';
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/server/models/user.js:
--------------------------------------------------------------------------------
1 | var mongoose = require("mongoose");
2 | var util = require("../config/util.js");
3 |
4 | var UserSchema = mongoose.Schema({
5 | name: String,
6 | email: String,
7 | password: String,
8 | lastConnection: { type: Date, default: Date.now },
9 | });
10 |
11 | UserSchema.methods = {
12 | authenticate: function (plainText) {
13 | return util.encrypt(plainText) == this.password;
14 | },
15 | };
16 |
17 | mongoose.model("User", UserSchema);
18 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "scripts": {
7 | "start": "nodemon app.js"
8 | },
9 | "dependencies": {
10 | "config": "^3.3.6",
11 | "express": "^4.17.2",
12 | "js-chess-engine": "^1.0.2",
13 | "mongodb": "^4.2.2",
14 | "mongoose": "^6.1.3",
15 | "path": "^0.12.7",
16 | "request": "^2.88.2",
17 | "socket.io": "^2.3.0",
18 | "sqlite3": "^5.1.7"
19 | },
20 | "devDependencies": {
21 | "nodemon": "^2.0.4"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/server/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | React App
12 |
13 |
14 | You need to enable JavaScript to run this app.
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/server/routes/token.js:
--------------------------------------------------------------------------------
1 | /* learn more: https://github.com/testing-library/jest-dom // @testing-library/jest-dom library provides a set of custom jest matchers that you can use to extend jest. These will make your tests more declarative, clear to read and to maintain.*/
2 | const express = require("express");
3 | const router = express.Router();
4 | const axios = require('axios');
5 | const asyncErrorHandler = require("../config/middleware")
6 |
7 | const util = require("../config/util");
8 |
9 | router.get("/token", function (req, res, next) {
10 | res.send(util.randomString(20));
11 | });
12 |
13 | module.exports = router;
14 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import "./App.scss";
2 | import { useState, useEffect } from "react";
3 | import { BrowserRouter, Routes, Route } from "react-router-dom";
4 | import GameSelect from "./components/UI/GameSelect/GameSelect";
5 | import Level from "./components/UI/Level/Level";
6 | import FriendPlay from "./views/FriendPlay";
7 | import GameScene from "./views/GameScene";
8 | import MatchPlay from "./views/MatchPlay";
9 | import Orientation from "./components/UI/Orientation/Orientation";
10 | import Connect from "./components/UI/Connect/Connect";
11 | import Ranking from "./components/UI/Ranking/Ranking";
12 |
13 | function App() {
14 | const [orientation, setOrientation] = useState(false);
15 |
16 | useEffect(() => {
17 | window.screen.orientation.lock("landscape").catch((e) => {
18 | console.log(e);
19 | });
20 | window.addEventListener(
21 | "resize",
22 | function () {
23 | setOrientation(window.innerHeight > window.innerWidth);
24 | },
25 | false
26 | );
27 | setOrientation(window.innerHeight > window.innerWidth);
28 | }, []);
29 |
30 | return (
31 |
32 |
33 |
34 | } />
35 | } />
36 | } />
37 | } />
38 | } />
39 | } />
40 | } />
41 |
42 |
43 |
44 |
45 | );
46 | }
47 |
48 | export default App;
49 |
--------------------------------------------------------------------------------
/src/App.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "Haettenschweiler";
3 | src: local("Haettenschweiler"),
4 | url("./assets/fonts/Haettenschweiler.ttf") format("truetype"); /* Super Modern Browsers */
5 | }
6 |
7 | @font-face {
8 | font-family: "HaettenschweilerRegular";
9 | src: local("HaettenschweilerRegular"),
10 | url("./assets/fonts/Haettenschweiler Regular.ttf") format("truetype"); /* Super Modern Browsers */
11 | }
12 |
13 | @font-face {
14 | font-family: "ErasBoldItc";
15 | src: local("ErasBoldItc"),
16 | url("./assets/fonts/Eras Bold ITC.ttf") format("truetype"); /* Super Modern Browsers */
17 | }
18 |
19 | .App {
20 | position: relative;
21 | width: 100vw;
22 | height: 100vh;
23 | }
24 |
25 | .fullScreen {
26 | position: relative;
27 | width: 100%;
28 | height: 100%;
29 | }
30 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render( );
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/src/assets/audio/gameselect.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/audio/gameselect.mp3
--------------------------------------------------------------------------------
/src/assets/fonts/Eras Bold ITC.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/fonts/Eras Bold ITC.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Haettenschweiler Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/fonts/Haettenschweiler Regular.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/Haettenschweiler.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/fonts/Haettenschweiler.ttf
--------------------------------------------------------------------------------
/src/assets/img/1v1_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_back.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_classic_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_classic_bg.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_classic_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_classic_header.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_diamond_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_diamond_bg.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_diamond_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_diamond_header.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_gold_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_gold_bg.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_gold_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_gold_header.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_header.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_platinum_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_platinum_bg.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_platinum_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_platinum_header.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_silver_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_silver_bg.png
--------------------------------------------------------------------------------
/src/assets/img/1v1_silver_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/1v1_silver_header.png
--------------------------------------------------------------------------------
/src/assets/img/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/Thumbs.db
--------------------------------------------------------------------------------
/src/assets/img/back_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/back_bg.png
--------------------------------------------------------------------------------
/src/assets/img/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/background.jpg
--------------------------------------------------------------------------------
/src/assets/img/blue_button_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/blue_button_bg.png
--------------------------------------------------------------------------------
/src/assets/img/classic_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/classic_bg.png
--------------------------------------------------------------------------------
/src/assets/img/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/close.png
--------------------------------------------------------------------------------
/src/assets/img/coming-soon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/coming-soon.png
--------------------------------------------------------------------------------
/src/assets/img/confirm_btn_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/confirm_btn_bg.png
--------------------------------------------------------------------------------
/src/assets/img/copybutton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/copybutton.png
--------------------------------------------------------------------------------
/src/assets/img/diamond_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/diamond_bg.png
--------------------------------------------------------------------------------
/src/assets/img/gold_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/gold_bg.png
--------------------------------------------------------------------------------
/src/assets/img/inputbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/inputbox.png
--------------------------------------------------------------------------------
/src/assets/img/items/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/items/Thumbs.db
--------------------------------------------------------------------------------
/src/assets/img/items/iceWall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/items/iceWall.png
--------------------------------------------------------------------------------
/src/assets/img/items/jumpyShoe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/items/jumpyShoe.png
--------------------------------------------------------------------------------
/src/assets/img/items/petrify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/items/petrify.png
--------------------------------------------------------------------------------
/src/assets/img/items/springPad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/items/springPad.png
--------------------------------------------------------------------------------
/src/assets/img/items/thunderstorm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/items/thunderstorm.png
--------------------------------------------------------------------------------
/src/assets/img/left_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/left_banner.png
--------------------------------------------------------------------------------
/src/assets/img/level_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/level_back.png
--------------------------------------------------------------------------------
/src/assets/img/ll_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/ll_logo.png
--------------------------------------------------------------------------------
/src/assets/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/logo.png
--------------------------------------------------------------------------------
/src/assets/img/modal_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/modal_back.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_bishop_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_bishop_bg.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_bishop_cyborg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_bishop_cyborg.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_bishop_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_bishop_icon.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_knight_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_knight_bg.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_knight_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_knight_icon.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_knight_wolf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_knight_wolf.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_queen_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_queen_bg.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_queen_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_queen_icon.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_queen_medusa_fox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_queen_medusa_fox.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_rook_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_rook_bg.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_rook_dragon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_rook_dragon.png
--------------------------------------------------------------------------------
/src/assets/img/pawn_rook_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/pawn_rook_icon.png
--------------------------------------------------------------------------------
/src/assets/img/platinum_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/platinum_bg.png
--------------------------------------------------------------------------------
/src/assets/img/popup_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/popup_bg.png
--------------------------------------------------------------------------------
/src/assets/img/ranking/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/ranking/1.png
--------------------------------------------------------------------------------
/src/assets/img/ranking/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/ranking/2.png
--------------------------------------------------------------------------------
/src/assets/img/ranking/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/ranking/3.png
--------------------------------------------------------------------------------
/src/assets/img/ranking/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/ranking/Thumbs.db
--------------------------------------------------------------------------------
/src/assets/img/ribbon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/ribbon.png
--------------------------------------------------------------------------------
/src/assets/img/right_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/right_banner.png
--------------------------------------------------------------------------------
/src/assets/img/scene_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_back.png
--------------------------------------------------------------------------------
/src/assets/img/scene_clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_clock.png
--------------------------------------------------------------------------------
/src/assets/img/scene_fore_volcano.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_fore_volcano.png
--------------------------------------------------------------------------------
/src/assets/img/scene_left_volcano.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_left_volcano.png
--------------------------------------------------------------------------------
/src/assets/img/scene_right_volcano.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_right_volcano.png
--------------------------------------------------------------------------------
/src/assets/img/scene_setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_setting.png
--------------------------------------------------------------------------------
/src/assets/img/scene_undo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_undo.png
--------------------------------------------------------------------------------
/src/assets/img/scene_user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_user.png
--------------------------------------------------------------------------------
/src/assets/img/scene_user_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_user_bg.png
--------------------------------------------------------------------------------
/src/assets/img/scene_volcano.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/scene_volcano.png
--------------------------------------------------------------------------------
/src/assets/img/select_game_computer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/select_game_computer.png
--------------------------------------------------------------------------------
/src/assets/img/select_game_friend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/select_game_friend.png
--------------------------------------------------------------------------------
/src/assets/img/select_game_random.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/select_game_random.png
--------------------------------------------------------------------------------
/src/assets/img/silver_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/silver_bg.png
--------------------------------------------------------------------------------
/src/assets/img/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/star.png
--------------------------------------------------------------------------------
/src/assets/img/star_none.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/star_none.png
--------------------------------------------------------------------------------
/src/assets/img/surrender-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/surrender-icon.png
--------------------------------------------------------------------------------
/src/assets/img/victory_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/victory_button.png
--------------------------------------------------------------------------------
/src/assets/img/victory_container.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/victory_container.png
--------------------------------------------------------------------------------
/src/assets/img/victory_item1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/victory_item1.png
--------------------------------------------------------------------------------
/src/assets/img/victory_item2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/victory_item2.png
--------------------------------------------------------------------------------
/src/assets/img/victory_mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dev-knight0227/Chess-project/09ecfa49f31c15d1a20c3d1bf6544676b66228d6/src/assets/img/victory_mark.png
--------------------------------------------------------------------------------
/src/components/UI/Claim/Claim.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { Modal } from "react-bootstrap";
3 | import "bootstrap/dist/css/bootstrap.min.css";
4 | import "./Claim.scss";
5 |
6 | export const Claim = ({ show, msg, onClickClaim, btnText }) => {
7 | const [loading, setLoading] = useState(false);
8 |
9 | const onClick = () => {
10 | if(loading) return;
11 | onClickClaim();
12 | if(btnText == "Claim Reward") setLoading(true);
13 | }
14 | return (
15 |
22 |
23 |
Play to earn
24 |
25 |
26 |
{msg}
27 |
{loading ? "Loading..." : btnText}
28 |
29 |
30 |
31 |
32 | );
33 | };
34 |
35 | export default Claim;
36 |
--------------------------------------------------------------------------------
/src/components/UI/Claim/Claim.scss:
--------------------------------------------------------------------------------
1 | .Claim {
2 | font-family: "HaettenschweilerRegular";
3 | color: #fbfae2;
4 | .u-container {
5 | position: relative;
6 | width: 45vw;
7 | height: calc(45vw * 0.6);
8 | top: 5vw;
9 | margin: auto;
10 | background-image: url("../../../assets/img/level_back.png");
11 | background-repeat: no-repeat;
12 | background-size: 100% 100%;
13 | text-align: center;
14 | .u-ribbon {
15 | position: absolute;
16 | width: 60%;
17 | height: 6vw;
18 | left: 20%;
19 | top: -2.5vw;
20 | background-image: url("../../../assets/img/ribbon.png");
21 | background-repeat: no-repeat;
22 | background-size: 100% 100%;
23 | font-size: 3vw;
24 | text-align: center;
25 | font-family: "HaettenschweilerRegular", fantasy, Courier, monospace;
26 | color: #fbfae2;
27 | -webkit-text-stroke: 0.05em #792a4d;
28 | }
29 | .u-content {
30 | position: absolute;
31 | bottom: 0;
32 | width: 100%;
33 | height: calc(45vw * 0.6 - 3vw);
34 | display: grid;
35 | align-items: center;
36 | font-family: "HaettenschweilerRegular";
37 | color: #f9f8cb;
38 | .u-content-container {
39 | display: grid;
40 | align-items: center;
41 | width: 100%;
42 | height: 40%;
43 | .u-text {
44 | font-size: 2vw;
45 | }
46 | .u-button {
47 | margin: auto;
48 | background-image: url("../../../assets/img/victory_button.png");
49 | background-repeat: no-repeat;
50 | background-size: 100% 100%;
51 | -webkit-text-stroke: 0.05em #0c6c6d;
52 | width: 20vw;
53 | height: 5vw;
54 | font-size: 2.5vw;
55 | display: grid;
56 | text-align: center;
57 | align-items: center;
58 | cursor: pointer;
59 | &:active {
60 | font-size: 2.45vw;
61 | }
62 | }
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/components/UI/Confirm/Confirm.js:
--------------------------------------------------------------------------------
1 | import { Modal } from "react-bootstrap";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import "./Confirm.scss";
4 |
5 | export const Confirm = ({ show, msg, path, hideAction }) => {
6 | return (
7 |
14 |
15 |
{msg}
16 |
17 |
{
20 | window.location.href = path;
21 | }}
22 | >
23 | Yes
24 |
25 |
26 | No
27 |
28 |
29 |
30 |
31 | );
32 | };
33 |
34 | export default Confirm;
35 |
--------------------------------------------------------------------------------
/src/components/UI/Confirm/Confirm.scss:
--------------------------------------------------------------------------------
1 | .Confirm {
2 | font-family: "HaettenschweilerRegular";
3 | color: #fbfae2;
4 | .u-container {
5 | position: relative;
6 | width: 40vw;
7 | height: 30vw;
8 | margin: auto;
9 | background-image: url("../../../assets/img/back_bg.png");
10 | background-repeat: no-repeat;
11 | background-size: 100% 100%;
12 | .u-msg {
13 | height: 20vw;
14 | padding: 5vw;
15 | display: grid;
16 | text-align: center;
17 | align-items: center;
18 | font-size: 2vw;
19 | }
20 | .u-btn-group {
21 | position: absolute;
22 | bottom: 1vw;
23 | width: 100%;
24 | padding: 1vw;
25 | display: flex;
26 | justify-content: space-evenly;
27 | text-align: center;
28 | .u-btn-yes {
29 | display: grid;
30 | align-items: center;
31 | width: 10vw;
32 | padding: 0.1vw 1vw;
33 | background-image: url("../../../assets/img/victory_button.png");
34 | background-repeat: no-repeat;
35 | background-size: 100% 100%;
36 | font-size: 2.5vw;
37 | -webkit-text-stroke: 0.05em #0d6c6e;
38 | cursor: pointer;
39 | &:active {
40 | font-size: 2.45vw;
41 | }
42 | }
43 | .u-btn-no {
44 | display: grid;
45 | align-items: center;
46 | width: 10vw;
47 | padding: 0.1vw 1vw;
48 | background-image: url("../../../assets/img/victory_button.png");
49 | background-repeat: no-repeat;
50 | background-size: 100% 100%;
51 | font-size: 2.5vw;
52 | -webkit-text-stroke: 0.05em #0d6c6e;
53 | cursor: pointer;
54 | &:active {
55 | font-size: 2.45vw;
56 | }
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/components/UI/Connect/Connect.js:
--------------------------------------------------------------------------------
1 | import { useLocation, useNavigate } from 'react-router-dom'
2 | import { useState, useEffect } from 'react'
3 | import 'bootstrap/dist/css/bootstrap.min.css'
4 | import './Connect.scss'
5 | import { gameModes, userTypes } from "../../../utils/constant";
6 |
7 | import {
8 | connectWallet,
9 | getCurrentWalletConnected
10 | } from '../../../utils/interact.js'
11 | import {
12 | chainId,
13 | llgContractAddress,
14 | llgRewardContractAddress
15 | } from '../../../utils/address'
16 |
17 | import {
18 | getContractWithSigner,
19 | getContractWithoutSigner
20 | } from '../../../utils/interact'
21 | import { ethers } from 'ethers'
22 |
23 | const llgContractABI = require('../../../utils/llg-contract-abi.json')
24 | const llgRewardContractABI = require('../../../utils/llg-reward-contract-abi.json')
25 |
26 | let arrInfo = {}
27 |
28 | export const Connect = () => {
29 | const navigate = useNavigate()
30 | const location = useLocation()
31 | const [wallet, setWallet] = useState()
32 | const [status, setStatus] = useState()
33 | const [loading, setLoading] = useState(false)
34 |
35 | const [stage, setStage] = useState('connect')
36 |
37 | let amount
38 | let walletAddr;
39 |
40 | useEffect(() => {
41 | addWalletListener()
42 | })
43 |
44 | console.log(location.state);
45 |
46 | switch (location.state.roomName) {
47 | case 'Classic Room':
48 | amount = 0
49 | break
50 | case 'Silver Room':
51 | amount = 50
52 | break
53 | case 'Gold Room':
54 | amount = 100
55 | break
56 | case 'Platinum Room':
57 | amount = 200
58 | break
59 | case 'Diamond Room':
60 | amount = 500
61 | break
62 | default:
63 | }
64 |
65 | arrInfo = {
66 | connect: {
67 | text: 'You need ' + amount + ' LLG to start the game.',
68 | button: 'Connect Wallet'
69 | },
70 | join: {
71 | text: 'Transaction approve. You have deposited ' + amount + ' LLG',
72 | button: 'Join game'
73 | },
74 | deposit: {
75 | text: 'You need ' + amount + ' LLG to start the game.',
76 | button: 'Deposit LLG'
77 | },
78 | depositFail: {
79 | text: 'Transaction failed. You need ' + amount + 'LLG to start the game',
80 | button: 'Deposit LLG'
81 | }
82 | }
83 |
84 | /************************************************************************************* */
85 | const addWalletListener = () => {
86 | if (window.ethereum) {
87 | window.ethereum.on('accountsChanged', accounts => {
88 | if (accounts.length > 0) {
89 | // this.setState({
90 | // wallet: accounts[0],
91 | // status: 'Wallet connected'
92 | // })
93 | setWallet(accounts[0])
94 | setStatus('Wallet connected')
95 | } else {
96 | // this.setState({
97 | // wallet: '',
98 | // status: '🦊 Connect to Metamask.'
99 | // })
100 | setWallet('')
101 | setStatus('🦊 Connect to Metamask.')
102 | }
103 | })
104 | window.ethereum.on('chainChanged', chain => {
105 | this.connectWalletPressed()
106 | if (chain !== chainId) {
107 | }
108 | })
109 | } else {
110 | // this.setState({
111 | // status: (
112 | //
113 | // {' '}
114 | // 🦊{' '}
115 | // {/* */}
116 | // You must install Metamask, a virtual Ethereum wallet, in your
117 | // browser.(https://metamask.io/download.html)
118 | // {/* */}
119 | //
120 | // )
121 | // })
122 | let stat = (
123 |
124 | {' '}
125 | 🦊{' '}
126 | {/* */}
127 | You must install Metamask, a virtual Ethereum wallet, in your
128 | browser.(https://metamask.io/download.html)
129 | {/* */}
130 |
131 | )
132 |
133 | setStatus(stat)
134 | }
135 | }
136 |
137 | const connectWalletPressed = async () => {
138 | let walletResponse = await connectWallet()
139 | // this.setState({
140 | // status: walletResponse.status,
141 | // wallet: walletResponse.address
142 | // })
143 | setWallet(walletResponse.address)
144 | setStatus(walletResponse.status)
145 | walletAddr = walletResponse.address;
146 |
147 | // alert(walletResponse.address)
148 | return walletResponse.address != null
149 | }
150 |
151 | const makeDeposit = async () => {
152 | let llgContract = getContractWithSigner(
153 | llgContractAddress,
154 | llgContractABI
155 | )
156 |
157 | console.error(location.state.roomName + ' ' + location.state.roomKey)
158 |
159 | let amount = 50
160 | switch (location.state.roomName) {
161 | case 'Classic Room':
162 | amount = 0
163 | break
164 | case 'Silver Room':
165 | amount = 50
166 | break
167 | case 'Gold Room':
168 | amount = 100
169 | break
170 | case 'Platinum Room':
171 | amount = 200
172 | break
173 | case 'Diamond Room':
174 | amount = 500
175 | break
176 | default:
177 | }
178 |
179 | let spender = llgRewardContractAddress
180 |
181 | let tx = await llgContract.approve(
182 | ethers.utils.getAddress(spender),
183 | ethers.BigNumber.from(amount * 1000000000),
184 | {
185 | value: 0,
186 | from: wallet
187 | }
188 | )
189 |
190 | if (tx.code == 4001) return false
191 | let res = await tx.wait()
192 | if (res.transactionHash) {
193 | let llgRewardContract = getContractWithSigner(
194 | llgRewardContractAddress,
195 | llgRewardContractABI
196 | )
197 |
198 |
199 | let tx2 = await llgRewardContract.deposit(
200 | ethers.BigNumber.from(location.state.roomKey),
201 | ethers.utils.getAddress(wallet),
202 | ethers.BigNumber.from(amount),
203 | {
204 | value: 0,
205 | from: wallet
206 | }
207 | )
208 |
209 | if (tx2 == null) return false
210 |
211 | let res2 = await tx2.wait()
212 |
213 | if (res2.transactionHash) {
214 | return true
215 | } else {
216 | return false
217 | }
218 | } else {
219 | return false
220 | }
221 | }
222 |
223 | /************************************************************************************* */
224 |
225 | const nextStage = async () => {
226 | if (loading) return;
227 | setLoading(true)
228 | switch (stage) {
229 | case 'connect':
230 | try {
231 | let res = await connectWalletPressed()
232 | if (res) {
233 | if(walletAddr == null || walletAddr == '') break;
234 | if(location.state.roomName == "Classic Room") {
235 | navigate('/gameScene', { state: {...location.state, wallet: walletAddr} })
236 | } else {
237 | setStage('deposit')
238 | }
239 | }
240 | } catch (e) {
241 | alert('Please connect wallet...')
242 | }
243 | break
244 | case 'join':
245 | navigate('/gameScene', { state: {...location.state, wallet} })
246 | break
247 | case 'deposit':
248 | try {
249 | let res1 = await makeDeposit()
250 | if (res1) setStage('join')
251 | else setStage('depositFail')
252 | } catch (e) {
253 | setStage('depositFail')
254 | }
255 | break
256 | case 'depositFail':
257 | try {
258 | let res2 = await makeDeposit()
259 | if (res2) setStage('join')
260 | else setStage('depositFail')
261 | } catch (e) {
262 | setStage('depositFail')
263 | }
264 | break
265 | default:
266 | }
267 | setLoading(false)
268 | }
269 |
270 | return (
271 |
272 |
273 |
Play to earn
274 |
275 |
276 |
{arrInfo[stage].text}
277 |
278 |
nextStage()}>
279 | {loading ? 'Loading...' : arrInfo[stage].button}
280 |
281 |
282 |
283 |
284 |
285 | )
286 | }
287 |
288 | export default Connect
289 |
--------------------------------------------------------------------------------
/src/components/UI/Connect/Connect.scss:
--------------------------------------------------------------------------------
1 | .Connect {
2 | position: relative;
3 | background-image: url("../../../assets/img/modal_back.png");
4 | background-size: 100% 100%;
5 | background-repeat: no-repeat;
6 | position: relative;
7 | height: 100%;
8 | display: grid;
9 | align-items: center;
10 | .u-container {
11 | position: relative;
12 | width: 70vw;
13 | height: calc(70vw * 0.6);
14 | top: 1vw;
15 | margin: auto;
16 | background-image: url("../../../assets/img/level_back.png");
17 | background-repeat: no-repeat;
18 | background-size: 100% 100%;
19 | text-align: center;
20 | .u-ribbon {
21 | position: absolute;
22 | width: 60%;
23 | height: 6vw;
24 | left: 20%;
25 | top: -2.5vw;
26 | background-image: url("../../../assets/img/ribbon.png");
27 | background-repeat: no-repeat;
28 | background-size: 100% 100%;
29 | font-size: 3vw;
30 | text-align: center;
31 | font-family: "HaettenschweilerRegular", fantasy, Courier, monospace;
32 | color: #fbfae2;
33 | -webkit-text-stroke: 0.05em #792a4d;
34 | }
35 | .u-content {
36 | position: absolute;
37 | bottom: 0;
38 | width: 100%;
39 | height: calc(70vw * 0.6 - 3vw);
40 | display: grid;
41 | align-items: center;
42 | font-family: "HaettenschweilerRegular";
43 | color: #f9f8cb;
44 | .u-content-container {
45 | display: grid;
46 | align-items: center;
47 | width: 100%;
48 | height: 40%;
49 | .u-text {
50 | font-size: 2vw;
51 | }
52 | .u-button {
53 | margin: auto;
54 | background-image: url("../../../assets/img/victory_button.png");
55 | background-repeat: no-repeat;
56 | background-size: 100% 100%;
57 | -webkit-text-stroke: 0.05em #0c6c6d;
58 | width: 20vw;
59 | height: 5vw;
60 | font-size: 2.5vw;
61 | display: grid;
62 | text-align: center;
63 | align-items: center;
64 | cursor: pointer;
65 | &:active {
66 | font-size: 2.45vw;
67 | }
68 | }
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/components/UI/CreateGame/CreateGame.js:
--------------------------------------------------------------------------------
1 | import { useNavigate } from "react-router-dom";
2 |
3 | import "bootstrap/dist/css/bootstrap.min.css";
4 | import "./CreateGame.scss";
5 | import { useState } from "react";
6 |
7 | export const CreateGame = () => {
8 | const [name, setName] = useState('');
9 | const navigate = useNavigate();
10 |
11 | const createAction = () => {
12 | if( name === '' )
13 | return;
14 |
15 | navigate('/friendPlay/rooms', { state: { username: name, friendMatch: true }});
16 | }
17 |
18 | return (
19 |
20 |
21 |
Create game
22 |
23 |
24 |
25 |
26 | setName(e.target.value)}
31 | onKeyDown={(e) => e.key === 'Enter' ? createAction() : null}
32 | />
33 |
34 |
35 |
36 | Create
37 |
38 |
39 |
40 |
41 | )
42 | }
43 |
44 | export default CreateGame;
--------------------------------------------------------------------------------
/src/components/UI/CreateGame/CreateGame.scss:
--------------------------------------------------------------------------------
1 | .CreateGame {
2 | background-image: url("../../../assets/img/modal_back.png");
3 | background-size: 100% 100%;
4 | background-repeat: no-repeat;
5 | position: relative;
6 | height: 100vh;
7 | display: grid;
8 | align-items: center;
9 |
10 | .u-container {
11 | position: relative;
12 | width: 70vw;
13 | height: calc(70vw * 0.6);
14 | top: 1vw;
15 | margin: auto;
16 | background-image: url("../../../assets/img/level_back.png");
17 | background-repeat: no-repeat;
18 | background-size: 100% 100%;
19 | text-align: center;
20 | vertical-align: middle;
21 |
22 | .u-ribbon {
23 | position: absolute;
24 | width: 60%;
25 | height: 6vw;
26 | left: 20%;
27 | top: -2.5vw;
28 | background-image: url("../../../assets/img/ribbon.png");
29 | background-repeat: no-repeat;
30 | background-size: 100% 100%;
31 | font-size: 3vw;
32 | text-align: center;
33 | font-family: Haettenschweiler, fantasy, Courier, monospace;
34 | color: #fbfae2;
35 | -webkit-text-stroke: 0.05em #792a4d;
36 | }
37 |
38 | .u-content {
39 | position: absolute;
40 | bottom: 0;
41 | width: 100%;
42 | height: calc(70vw * 0.6 - 3vw);
43 |
44 | .u-logo {
45 | position: absolute;
46 | margin: 1vw;
47 | width: 40%;
48 | height: 20vw;
49 | left: 30%;
50 | top: 0.5vw;
51 | background-image: url("../../../assets/img/logo.png");
52 | background-repeat: no-repeat;
53 | background-size: 100% 100%;
54 | }
55 |
56 | .u-input-wrap {
57 | margin-top: 20vw;
58 | padding: 1vw;
59 | height: 7vw;
60 | display: flex;
61 | justify-content: center;
62 | align-items: center;
63 |
64 | .u-input {
65 | text-align: center;
66 | background: url(../../../assets/img/inputbox.png);
67 | background-repeat: no-repeat;
68 | background-size: 100% 100%;
69 | width: 40%;
70 | height: 5vw;
71 | border-width: 0;
72 | border-radius: 2.5vw;
73 | font-size: 2vw;
74 | color: white;
75 | padding-left: 0.5em;
76 | font-family: Haettenschweiler, fantasy, Courier, monospace;
77 | }
78 |
79 | .u-input {
80 | outline: none;
81 | border: 0;
82 | }
83 | }
84 |
85 | .u-buttongroup {
86 | display: inline-grid;
87 | .u-button {
88 | text-align: center;
89 | align-items: center;
90 | background-image: url("../../../assets/img/victory_button.png");
91 | background-repeat: no-repeat;
92 | background-size: 100% 100%;
93 | width: 14vw;
94 | height: 5vw;
95 | border-radius: 100px;
96 | color: #f9f8cb;
97 | font-family: Haettenschweiler, fantasy, Courier, monospace;
98 | font-size: 2.5vw;
99 | background-color: transparent;
100 | border-color: transparent;
101 | text-shadow: -1px 1px 1px #0d6c6e, 1px 1px 1px #0d6c6e,
102 | 1px -1px 1px #0d6c6e, -1px -1px 1px #0d6c6e;
103 | }
104 |
105 | .u-button:active {
106 | font-size: 2.4vw;
107 | }
108 | }
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/components/UI/GameSelect/GameSelect.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { useNavigate } from "react-router-dom";
3 | import { Image } from "react-bootstrap";
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 | import "./GameSelect.scss";
6 | import mode1Img from "../../../assets/img/select_game_random.png";
7 | import mode2Img from "../../../assets/img/select_game_friend.png";
8 | import mode3Img from "../../../assets/img/select_game_computer.png";
9 | import song from "../../../assets/audio/gameselect.mp3";
10 | import useSound from "use-sound";
11 |
12 | export const GameSelect = () => {
13 | const [playSong] = useSound(song);
14 | const navigate = useNavigate();
15 |
16 | const matchPlayAction = () => {
17 | navigate("/matchPlay");
18 | playSong();
19 | };
20 |
21 | const friendPlayAction = () => {
22 | navigate("/friendPlay");
23 | playSong();
24 | };
25 |
26 | const machinePlayAction = () => {
27 | navigate("/machinePlay");
28 | playSong();
29 | };
30 |
31 | return (
32 |
33 |
34 |
Select game
35 |
36 |
37 |
38 |
Match with Random User
39 |
40 |
41 |
42 |
Match with Friend
43 |
44 |
45 |
46 |
Match with Computer
47 |
48 |
49 |
50 |
51 | );
52 | };
53 |
54 | export default GameSelect;
55 |
--------------------------------------------------------------------------------
/src/components/UI/GameSelect/GameSelect.scss:
--------------------------------------------------------------------------------
1 | .GameSelect {
2 | background-image: url("../../../assets/img/modal_back.png");
3 | background-size: 100% 100%;
4 | background-repeat: no-repeat;
5 | position: relative;
6 | height: 100%;
7 | display: grid;
8 | align-items: center;
9 |
10 | .u-container {
11 | position: relative;
12 | width: 70vw;
13 | height: calc(70vw * 0.6);
14 | top: 1vw;
15 | margin: auto;
16 | background-image: url("../../../assets/img/level_back.png");
17 | background-repeat: no-repeat;
18 | background-size: 100% 100%;
19 | text-align: center;
20 | vertical-align: middle;
21 |
22 | .u-content {
23 | position: relative;
24 | width: 50vw;
25 | height: calc(50vw * 0.6);
26 | }
27 | .u-ribbon {
28 | position: absolute;
29 | width: 60%;
30 | height: 6vw;
31 | left: 20%;
32 | top: -2.5vw;
33 | background-image: url("../../../assets/img/ribbon.png");
34 | background-repeat: no-repeat;
35 | background-size: 100% 100%;
36 | font-size: 3vw;
37 | text-align: center;
38 | font-family: "HaettenschweilerRegular", fantasy, Courier, monospace;
39 | color: #fbfae2;
40 | -webkit-text-stroke: 0.05em #792a4d;
41 | }
42 | .u-content {
43 | position: absolute;
44 | bottom: 0;
45 | width: 100%;
46 | height: calc(70vw * 0.6 - 3vw);
47 | display: flex;
48 | justify-content: space-evenly;
49 | align-items: center;
50 |
51 | .u-item {
52 | position: relative;
53 | width: 20vw;
54 |
55 | .u-item-image {
56 | width: 100%;
57 | }
58 |
59 | .u-item-text {
60 | position: absolute;
61 | width: 100%;
62 | height: 33%;
63 | bottom: 0;
64 | display: grid;
65 | text-align: center;
66 | align-items: center;
67 | font-family: "HaettenschweilerRegular", fantasy, Courier, monospace;
68 | color: #fbfae2;
69 | -webkit-text-stroke: 0.025em #390b13;
70 | font-size: 1.5vw;
71 | }
72 |
73 | .u-item-image:active {
74 | width: 19.9vw;
75 | }
76 |
77 | &:hover {
78 | cursor: pointer;
79 | }
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/components/UI/GameState/GameStateFooter.js:
--------------------------------------------------------------------------------
1 | import "./GameStateFooter.scss";
2 |
3 | export const GameStateFooter = ({quitAction, showInventoryAction, sendDrawRequest}) => {
4 |
5 | return (
6 |
13 | );
14 | };
15 |
16 | export default GameStateFooter;
17 |
--------------------------------------------------------------------------------
/src/components/UI/GameState/GameStateFooter.scss:
--------------------------------------------------------------------------------
1 | .GameStateFooter {
2 | position: absolute;
3 | width: 100%;
4 | height: 0;
5 | bottom: 0;
6 | // background-image: url("../../../assets/img/scene_volcano.png");
7 | // background-repeat: no-repeat;
8 | // background-size: 100% 100%;
9 |
10 | * {
11 | color: #ffffff;
12 | -webkit-text-stroke: 0.05em #100205;
13 | }
14 |
15 | .u-back {
16 | transform: rotate(90deg);
17 | position: absolute;
18 | left: 2vw;
19 | bottom: 1vw;
20 | width: 5vw;
21 | height: 5vw;
22 | background-image: url("../../../assets/img/scene_back.png");
23 | background-repeat: no-repeat;
24 | background-size: 100% 100%;
25 |
26 | &:hover {
27 | cursor: pointer;
28 | }
29 |
30 | &:active {
31 | width: 4.9vw;
32 | height: 4.9vw;
33 | }
34 | }
35 |
36 | .u-footer-right {
37 | position: absolute;
38 | right: 2vw;
39 | bottom: 1vw;
40 | display: flex;
41 | justify-content: space-between;
42 | // width: 11vw;
43 |
44 | .u-undo {
45 | width: 5vw;
46 | height: 5vw;
47 | background-image: url("../../../assets/img/scene_undo.png");
48 | background-repeat: no-repeat;
49 | background-size: 100% 100%;
50 | cursor: pointer;
51 |
52 | &:active {
53 | width: 4.9vw;
54 | height: 4.9vw;
55 | }
56 | }
57 |
58 | .u-draw {
59 | width: 5vw;
60 | height: 5vw;
61 | background-image: url("../../../assets/img/surrender-icon.png");
62 | background-repeat: no-repeat;
63 | background-size: 100% 100%;
64 | cursor: pointer;
65 | margin: 0 1vw;
66 |
67 | &:active {
68 | width: 4.9vw;
69 | height: 4.9vw;
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/components/UI/GameState/GameStateHeader.js:
--------------------------------------------------------------------------------
1 | import "./GameStateHeader.scss";
2 |
3 | export const GameStateHeader = ({ opponentName, myTurn, remainingTime }) => {
4 | const formatTime = (time) => {
5 | if (!time) {
6 | return "-- : --";
7 | }
8 |
9 | const minutes =
10 | Math.floor(time / 60) < 10
11 | ? "0" + Math.floor(time / 60)
12 | : Math.floor(time / 60);
13 | const seconds = time % 60 < 10 ? "0" + (time % 60) : time % 60;
14 |
15 | return minutes + " : " + seconds;
16 | };
17 |
18 | return (
19 |
20 |
30 |
31 |
32 |
33 | {myTurn ? formatTime(remainingTime) : "-- : --"}
34 |
35 |
36 |
37 | {!myTurn ? formatTime(remainingTime) : "-- : --"}
38 |
39 |
40 |
41 |
42 |
43 |
44 |
47 |
{opponentName}
48 |
49 |
50 |
51 |
52 | );
53 | };
54 |
55 | export default GameStateHeader;
56 |
--------------------------------------------------------------------------------
/src/components/UI/GameState/GameStateHeader.scss:
--------------------------------------------------------------------------------
1 | .GameStateHeader {
2 | position: absolute;
3 | width: 100%;
4 | height: 0;
5 | top: 0;
6 |
7 | * {
8 | color: #ffffff;
9 | -webkit-text-stroke: 0.05em #100205;
10 | }
11 |
12 | .u-you-container {
13 | position: absolute;
14 | top: 1vw;
15 | left: 2vw;
16 | width: 16vw;
17 |
18 | .u-black {
19 | position: absolute;
20 | top: 1vw;
21 | left: 1vw;
22 | width: 100%;
23 | height: 3vw;
24 | background-color: rgba($color: #000000, $alpha: 0.4);
25 | border: 1px solid #9789bd;
26 | border-radius: 1.5vw;
27 | }
28 |
29 | .u-info {
30 | position: absolute;
31 | top: 0;
32 | left: 0;
33 |
34 | .u-info-img-back {
35 | width: 8vw;
36 | height: 8vw;
37 | background-image: url("../../../assets/img/scene_user_bg.png");
38 | background-repeat: no-repeat;
39 | background-size: 100% 100%;
40 | display: grid;
41 | align-items: center;
42 | text-align: center;
43 |
44 | .u-info-img {
45 | width: 6.4vw;
46 | height: 6.4vw;
47 | background-image: url("../../../assets/img/scene_user.png");
48 | background-repeat: no-repeat;
49 | background-size: 100% 100%;
50 | border-radius: 3.2vw;
51 | margin: auto;
52 | }
53 | }
54 |
55 | .u-info-name {
56 | padding: 0.1vw;
57 | display: grid;
58 | text-align: center;
59 | align-items: center;
60 | font-family: "ErasBoldItc";
61 | font-size: 1.5vw;
62 | font-weight: bold;
63 | }
64 | }
65 |
66 | .u-left-banner {
67 | position: absolute;
68 | top: 1vw;
69 | right: -2vw;
70 | width: 3vw;
71 | height: 3vw;
72 | background-image: url("../../../assets/img/left_banner.png");
73 | background-repeat: no-repeat;
74 | background-size: 100% 100%;
75 |
76 | &.hide {
77 | display: none;
78 | }
79 |
80 | &.show {
81 | display: block;
82 | }
83 | }
84 | }
85 |
86 | .u-time-container {
87 | position: absolute;
88 | top: 1vw;
89 | transform: translate3d(-50%, 0, 0);
90 | left: 50%;
91 | display: flex;
92 | justify-content: space-between;
93 | align-items: center;
94 |
95 | .u-time {
96 | background-color: rgba($color: #000000, $alpha: 0.4);
97 | border: 1px solid #9789bd;
98 | width: 14vw;
99 | height: 2.8vw;
100 | border-radius: 1.4vw;
101 | text-align: center;
102 | align-items: center;
103 | font-family: "ErasBoldItc";
104 | font-size: 2vw;
105 | }
106 |
107 | .u-clock {
108 | width: 5vw;
109 | height: 5vw;
110 | margin: 0 1vw;
111 | background-image: url("../../../assets/img/scene_clock.png");
112 | background-repeat: no-repeat;
113 | background-size: 100% 100%;
114 | }
115 | }
116 |
117 | .u-opponent-container {
118 | position: absolute;
119 | width: 16vw;
120 | top: 1vw;
121 | right: 2vw;
122 |
123 | .u-black {
124 | position: absolute;
125 | top: 1vw;
126 | right: 1vw;
127 | width: 100%;
128 | height: 3vw;
129 | background-color: rgba($color: #000000, $alpha: 0.4);
130 | border: 1px solid #9789bd;
131 | border-radius: 1.5vw;
132 | }
133 |
134 | .u-info {
135 | position: absolute;
136 | top: 0;
137 | right: 0;
138 |
139 | .u-info-img-back {
140 | width: 8vw;
141 | height: 8vw;
142 | background-image: url("../../../assets/img/scene_user_bg.png");
143 | background-repeat: no-repeat;
144 | background-size: 100% 100%;
145 | display: grid;
146 | align-items: center;
147 | text-align: center;
148 |
149 | .u-info-img {
150 | width: 6.4vw;
151 | height: 6.4vw;
152 | background-image: url("../../../assets/img/scene_user.png");
153 | background-repeat: no-repeat;
154 | background-size: 100% 100%;
155 | border-radius: 3.2vw;
156 | margin: auto;
157 | }
158 | }
159 |
160 | .u-info-name {
161 | padding: 0.1vw;
162 | display: grid;
163 | text-align: center;
164 | align-items: center;
165 | font-family: "ErasBoldItc";
166 | font-size: 1.5vw;
167 | font-weight: bold;
168 | }
169 | }
170 |
171 | .u-right-banner {
172 | position: absolute;
173 | top: 1vw;
174 | left: -2vw;
175 | width: 3vw;
176 | height: 3vw;
177 | background-image: url("../../../assets/img/right_banner.png");
178 | background-repeat: no-repeat;
179 | background-size: 100% 100%;
180 |
181 | &.hide {
182 | display: none;
183 | }
184 |
185 | &.show {
186 | display: block;
187 | }
188 | }
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/src/components/UI/Inventory/Inventory.js:
--------------------------------------------------------------------------------
1 | import './Inventory.scss';
2 | import iceWall from '../../../assets/img/items/iceWall.png';
3 | import petrify from '../../../assets/img/items/petrify.png';
4 | import jumpyShoe from '../../../assets/img/items/jumpyShoe.png';
5 |
6 | import { heroItems } from '../../../utils/constant';
7 |
8 | import OverlayTrigger from "react-bootstrap/OverlayTrigger";
9 | import Tooltip from "react-bootstrap/Tooltip";
10 |
11 | export const Inventory = ({ show, items, myTurn, selectItem, currentItem }) => {
12 | const isEnable = (type) => {
13 | if( !items )
14 | return false;
15 |
16 | const idx = items.findIndex((item) => item.type === type);
17 | if( idx !== -1 )
18 | return true;
19 |
20 | return false;
21 | }
22 |
23 | const itemSelectAction = (item) => {
24 | if( !myTurn )
25 | return;
26 |
27 | selectItem(item);
28 | }
29 |
30 | const renderIceWallTooltip = props => (
31 | ✅ Ice Wall - block movement in 3 space blocks
32 | );
33 |
34 | const renderPetrifyTooltip = props => (
35 | ✅ Petrify - immobilize opponent's hero piece (except King or Queen)
36 | );
37 |
38 | const renderJumpyShoeTooltip = props => (
39 | ✅ Jumpy Shoe - Jump over obstacle
40 | );
41 |
42 | const enteringAction = (e) => {
43 | e.children[0].style.borderBottomColor = '#0000008c';
44 | e.children[1].style.backgroundColor = '#0000008c';
45 | }
46 |
47 | return (
48 |
49 |
50 |
51 | itemSelectAction( heroItems['iceWall'] )}
54 | >
55 |
56 |
57 |
58 |
59 |
60 | itemSelectAction( heroItems['petrify'] )}
63 | >
64 |
65 |
66 |
67 |
68 |
69 | itemSelectAction( heroItems['jumpyShoe'] )}
72 | >
73 |
74 |
75 |
76 |
77 |
78 | )
79 | }
80 |
81 | export default Inventory;
--------------------------------------------------------------------------------
/src/components/UI/Inventory/Inventory.scss:
--------------------------------------------------------------------------------
1 | @keyframes invenAnim {
2 | 0% {transform: scale(1);}
3 | 50% {transform: scale(1.3);}
4 | 100% {transform: scale(1);}
5 | }
6 |
7 | .inventory {
8 | position: absolute;
9 | transform: translate3d(0, -50%, 0);
10 | top: 50%;
11 |
12 | width: 8vw;
13 | height: 50%;
14 |
15 | background: #016da3de;
16 | border: 0.3vw solid #413348e0;
17 | border-radius: 1vw;
18 |
19 | transition: all 1s;
20 |
21 | display: flex;
22 | align-items: center;
23 | justify-content: center;
24 |
25 | &.show {
26 | left: -1vw;
27 | }
28 |
29 | &.hide {
30 | left: -8vw;
31 | }
32 |
33 | &__wrapper {
34 | display: flex;
35 | align-items: center;
36 | justify-content: center;
37 | flex-direction: column;
38 | transition: all 0.25s;
39 |
40 | .item {
41 | position: relative;
42 | margin: 1.5vw 0;
43 | width: 4.5vw;
44 |
45 | img {
46 | width: 100%;
47 | }
48 |
49 | &.enable {
50 | opacity: 1;
51 | }
52 |
53 | &.disable {
54 | opacity: 0.2;
55 | }
56 |
57 | &.active {
58 | animation: invenAnim .5s linear infinite;
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/src/components/UI/InviteFriend/InviteFriend.js:
--------------------------------------------------------------------------------
1 | import React, { useRef } from "react";
2 | import { Modal } from "react-bootstrap";
3 | import "bootstrap/dist/css/bootstrap.min.css";
4 | import "./InviteFriend.scss";
5 |
6 | export const InviteFriend = ({ show, hideAction, roomId }) => {
7 | const inputRef = useRef(null);
8 |
9 | const copyCodeToClipboard = () => {
10 | const el = inputRef.current;
11 | el.select();
12 | document.execCommand('copy');
13 | }
14 |
15 | return (
16 |
24 |
25 |
Invite Your friend
26 |
27 |
28 |
36 |
37 |
38 |
39 | Share the secret key above, so your friend can join this game!
40 |
41 |
Got it
42 |
43 |
44 |
45 | )
46 | }
47 |
48 | export default InviteFriend;
--------------------------------------------------------------------------------
/src/components/UI/InviteFriend/InviteFriend.scss:
--------------------------------------------------------------------------------
1 | .Play2Earn {
2 | display: grid !important;
3 | align-items: center;
4 |
5 | .u-container {
6 | position: relative;
7 | width: 70vw;
8 | height: calc(70vw * 0.6);
9 | top: 1vw;
10 | margin: auto;
11 | background-image: url("../../../assets/img/level_back.png");
12 | background-repeat: no-repeat;
13 | background-size: 100% 100%;
14 | text-align: center;
15 | vertical-align: middle;
16 |
17 | transform: translate3d(-50%, -50%, 0);
18 | left: 50%;
19 | top: 21vw;
20 |
21 | .u-ribbon {
22 | position: absolute;
23 | width: 60%;
24 | height: 6vw;
25 | left: 20%;
26 | top: -2.5vw;
27 | background-image: url("../../../assets/img/ribbon.png");
28 | background-repeat: no-repeat;
29 | background-size: 100% 100%;
30 | font-size: 3vw;
31 | text-align: center;
32 | font-family: Haettenschweiler, fantasy, Courier, monospace;
33 | color: #fbfae2;
34 | -webkit-text-stroke: 0.05em #792a4d;
35 | }
36 |
37 | .u-content {
38 | position: absolute;
39 | bottom: 0;
40 | width: 100%;
41 | height: calc(70vw * 0.6 - 3vw);
42 |
43 | .u-input-wrap {
44 | margin-top: 5vw;
45 | padding: 0vw;
46 | height: 7vw;
47 | display: flex;
48 | justify-content: center;
49 | align-items: center;
50 |
51 | .u-input {
52 | text-align: center;
53 | background: url(../../../assets/img/inputbox.png);
54 | background-repeat: no-repeat;
55 | background-size: 100% 100%;
56 | width: 40%;
57 | height: 5vw;
58 | border-width: 0;
59 | border-radius: 2.5vw;
60 | font-size: 2vw;
61 | color: white;
62 | padding-left: 0.5em;
63 | font-family: Haettenschweiler, fantasy, Courier, monospace;
64 | }
65 | .u-copy-button {
66 | background-image: url("../../../assets/img/copybutton.png");
67 | background-repeat: no-repeat;
68 | background-size: 100% 100%;
69 | width: 6vw;
70 | height: 6vw;
71 | color: #f9f8cb;
72 | font-family: Haettenschweiler, fantasy, Courier, monospace;
73 | background-color: transparent;
74 | border-color: transparent;
75 | text-shadow: -1px 1px 1px #0d6c6e, 1px 1px 1px #0d6c6e,
76 | 1px -1px 1px #0d6c6e, -1px -1px 1px #0d6c6e;
77 | }
78 |
79 | .u-input {
80 | outline: none;
81 | border: 0;
82 | }
83 | }
84 | .u-description {
85 | background-color: rgba($color: #000000, $alpha: 0.2);
86 | border-radius: 1vw;
87 | width: 70%;
88 | height: 7vw;
89 | margin: 1vw auto;
90 | display: grid;
91 | align-items: center;
92 | padding: 2vw;
93 | padding-left: 6vw;
94 | font-size: 1.5vw;
95 | color: #fdf9e8;
96 | font-family: Arial;
97 | }
98 |
99 | .u-button {
100 | margin-top: 0vw;
101 | text-align: center;
102 | align-items: center;
103 | background-image: url("../../../assets/img/victory_button.png");
104 | background-repeat: no-repeat;
105 | background-size: 100% 100%;
106 | width: 14vw;
107 | height: 5vw;
108 | border-radius: 100px;
109 | color: #f9f8cb;
110 | font-family: Haettenschweiler, fantasy, Courier, monospace;
111 | font-size: 2.5vw;
112 | background-color: transparent;
113 | border-color: transparent;
114 | text-shadow: -1px 1px 1px #0d6c6e, 1px 1px 1px #0d6c6e,
115 | 1px -1px 1px #0d6c6e, -1px -1px 1px #0d6c6e;
116 | }
117 | .u-button:active {
118 | font-size: 2.45vw;
119 | }
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/components/UI/JoinGame/JoinGame.js:
--------------------------------------------------------------------------------
1 | import { useNavigate } from "react-router-dom";
2 | import { gameModes, userTypes } from "../../../utils/constant";
3 | import { useEffect, useState } from "react";
4 | import io from 'socket.io-client';
5 | import { socketServerPort } from "../../../config";
6 | import { socketEvents } from "../../../utils/packet";
7 | import store from "../../../store/store";
8 |
9 | import "bootstrap/dist/css/bootstrap.min.css";
10 | import "./JoinGame.scss";
11 |
12 | export const JoinGame = () => {
13 | const [name, setName] = useState('');
14 | const [secretKey, setSecretKey] = useState('');
15 | const navigate = useNavigate();
16 | const [ socket, setSocket ] = useState();
17 |
18 | const updateSocket = store( state => state.updateSocket );
19 |
20 | const joinAction = () => {
21 | if( name === '' || secretKey === '' )
22 | return;
23 |
24 | const data = {};
25 | data.username = name;
26 | data.friendMatch = true;
27 | data.roomId = secretKey;
28 |
29 | socket.emit( socketEvents['CS_JoinRoom'], data );
30 | }
31 |
32 | const handleJoinRoom = ( params ) => {
33 | const { roomName, roomKey } = params;
34 |
35 | const stateData = {
36 | mode: gameModes['P2P'],
37 | friendMatch: true,
38 | username: name,
39 | userType: userTypes['joiner'],
40 | roomId: secretKey,
41 | roomName: roomName,
42 | roomKey: roomKey,
43 | }
44 |
45 | if (roomName === 'Classic Room') {
46 | navigate('/gameScene', { state: { ...stateData } });
47 | } else {
48 | navigate('/connect', { state: { ...stateData } });
49 | }
50 | }
51 |
52 | useEffect(() => {
53 | const skt = io.connect(`http://${window.location.hostname}:${socketServerPort}`);
54 | setSocket( skt );
55 |
56 | skt.on( socketEvents['SC_JoinRoom'], (params) => handleJoinRoom(params) );
57 |
58 | updateSocket( skt );
59 | }, []);
60 |
61 | return (
62 |
63 |
64 |
Join game
65 |
66 |
67 |
68 | Name must have minimum 2 and maximum 20 characters
69 |
70 |
71 |
72 | setName(e.target.value)}
77 | onKeyDown={(e) => e.key === 'Enter' ? joinAction() : null}
78 | />
79 |
80 |
81 |
82 | setSecretKey(e.target.value)}
87 | onKeyDown={(e) => e.key === 'Enter' ? joinAction() : null}
88 | />
89 |
90 |
91 |
Join
92 |
93 |
94 |
95 | );
96 | }
97 |
98 | export default JoinGame;
--------------------------------------------------------------------------------
/src/components/UI/JoinGame/JoinGame.scss:
--------------------------------------------------------------------------------
1 | .JoinGame {
2 | background-image: url("../../../assets/img/modal_back.png");
3 | background-size: 100% 100%;
4 | background-repeat: no-repeat;
5 | position: relative;
6 | height: 100%;
7 | display: grid;
8 | align-items: center;
9 |
10 | .u-container {
11 | position: relative;
12 | width: 70vw;
13 | height: calc(70vw * 0.6);
14 | margin: auto;
15 | top: 1vw;
16 | background-image: url("../../../assets/img/level_back.png");
17 | background-repeat: no-repeat;
18 | background-size: 100% 100%;
19 | text-align: center;
20 |
21 | .u-ribbon {
22 | position: absolute;
23 | width: 60%;
24 | height: 6vw;
25 | left: 20%;
26 | top: -2.5vw;
27 | background-image: url("../../../assets/img/ribbon.png");
28 | background-repeat: no-repeat;
29 | background-size: 100% 100%;
30 | font-size: 3vw;
31 | text-align: center;
32 | font-family: "HaettenschweilerRegular", fantasy, Courier, monospace;
33 | color: #fbfae2;
34 | -webkit-text-stroke: 0.05em #792a4d;
35 | }
36 |
37 | .u-content {
38 | position: absolute;
39 | bottom: 0;
40 | width: 100%;
41 | height: calc(70vw * 0.6 - 3vw);
42 |
43 | .u-description {
44 | background-color: rgba($color: #000000, $alpha: 0.2);
45 | border-radius: 1vw;
46 | width: 70%;
47 | height: 7vw;
48 | margin: 1vw auto;
49 | display: grid;
50 | align-items: center;
51 | padding: 2vw;
52 | font-size: 1.5vw;
53 | color: #fdf9e8;
54 | font-family: Arial;
55 | }
56 |
57 | .u-input-wrap {
58 | padding: 1vw;
59 | height: 7vw;
60 |
61 | .u-input {
62 | text-align: center;
63 | background: url(../../../assets/img/inputbox.png);
64 | background-repeat: no-repeat;
65 | background-size: 100% 100%;
66 | width: 40%;
67 | height: 5vw;
68 | border-width: 0;
69 | border-radius: 2.5vw;
70 | font-size: 2.5vw;
71 | color: #fdf9e8;
72 | padding-left: 0.5em;
73 | font-family: "HaettenschweilerRegular", fantasy, Courier, monospace;
74 | outline: none;
75 | border: 0;
76 | }
77 |
78 | .u-input::placeholder {
79 | color: #84617b;
80 | }
81 | }
82 |
83 | .u-button {
84 | margin-top: 1vw;
85 | text-align: center;
86 | align-items: center;
87 | background-image: url("../../../assets/img/victory_button.png");
88 | background-repeat: no-repeat;
89 | background-size: 100% 100%;
90 | width: 14vw;
91 | height: 5vw;
92 | border-radius: 100px;
93 | color: #f9f8cb;
94 | font-family: "HaettenschweilerRegular", fantasy, Courier, monospace;
95 | font-size: 2.5vw;
96 | background-color: transparent;
97 | border-color: transparent;
98 | -webkit-text-stroke: 0.05em #0c6c6d;
99 | }
100 |
101 | .u-button:active {
102 | font-size: 2.4vw;
103 | }
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/components/UI/Level/Level.js:
--------------------------------------------------------------------------------
1 | import { useNavigate } from "react-router-dom";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import "./Level.scss";
4 | import { gameModes } from "../../../utils/constant";
5 |
6 | export const Level = () => {
7 | const navigate = useNavigate();
8 |
9 | const machinePlayAction = ( aiLevel ) => {
10 | navigate('/gameScene', { state: { mode: gameModes['P2E'], aiLevel: aiLevel } });
11 | }
12 |
13 | return (
14 |
15 |
16 |
Choose Level
17 |
18 |
19 |
20 |
21 |
22 | machinePlayAction(0)}>AI MonKey
23 |
24 |
25 | machinePlayAction(1)}>Beginner
26 |
27 |
28 |
29 |
30 | machinePlayAction(2)}>Intermediate
31 |
32 |
33 | machinePlayAction(3)}>Advanced
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | );
42 | }
43 |
44 | export default Level;
--------------------------------------------------------------------------------
/src/components/UI/Level/Level.scss:
--------------------------------------------------------------------------------
1 | .selectLevel {
2 | background-image: url("../../../assets/img/modal_back.png");
3 | background-size: 100% 100%;
4 | background-repeat: no-repeat;
5 | position: relative;
6 | width: 100%;
7 | height: 100%;
8 | display: grid;
9 | align-items: center;
10 |
11 | .u-container {
12 | position: relative;
13 | width: 70vw;
14 | height: calc(70vw * 0.6);
15 | top: 1vw;
16 | margin: auto;
17 | background-image: url("../../../assets/img/level_back.png");
18 | background-repeat: no-repeat;
19 | background-size: 100% 100%;
20 | text-align: center;
21 | vertical-align: middle;
22 |
23 | .u-content {
24 | position: relative;
25 | width: 50vw;
26 | height: calc(50vw * 0.6);
27 | }
28 |
29 | .u-ribbon {
30 | position: absolute;
31 | width: 60%;
32 | height: 6vw;
33 | left: 20%;
34 | top: -2.5vw;
35 | background-image: url("../../../assets/img/ribbon.png");
36 | background-repeat: no-repeat;
37 | background-size: 100% 100%;
38 | font-size: 3vw;
39 | text-align: center;
40 | font-family: Haettenschweiler, fantasy, Courier, monospace;
41 | color: #fbfae2;
42 | -webkit-text-stroke: 0.05em #792a4d;
43 | }
44 |
45 | .u-content {
46 | position: absolute;
47 | bottom: 0;
48 | width: 100%;
49 | height: calc(70vw * 0.6 - 3vw);
50 | display: grid;
51 |
52 | .u-content-container {
53 | width: 80%;
54 | height: 66%;
55 | margin: auto;
56 | display: grid;
57 | background-color: #422736;
58 | border-radius: 10px;
59 | border: 1px solid #80545b;
60 |
61 | .u-table-wrap {
62 | width: 100%;
63 | height: 100%;
64 | display: grid;
65 | padding: 5vw calc(5vw * 0.6);
66 |
67 | .u-row {
68 | display: flex;
69 | justify-content: space-evenly;
70 |
71 | .u-item-container {
72 | display: grid;
73 |
74 | .u-item {
75 | display: grid;
76 | align-self: center;
77 | align-items: center;
78 | background-image: url("../../../assets/img/victory_button.png");
79 | background-repeat: no-repeat;
80 | background-size: 100% 100%;
81 | width: 24vw;
82 | height: 90%;
83 | margin: auto;
84 | color: #f9f7c9;
85 | font-family: Haettenschweiler, fantasy, Courier, monospace;
86 | text-shadow: -2px 2px 2px #0d6c6e, 2px 2px 2px #0d6c6e,
87 | 2px -2px 2px #0d6c6e, -2px -2px 2px #0d6c6e;
88 | -webkit-text-stroke: 0.05em #0d6c6e;
89 | font-size: 2.5vw;
90 | background-color: transparent;
91 | border-color: transparent;
92 | }
93 |
94 | .u-item:active {
95 | font-size: 2.49vw;
96 | }
97 | }
98 | }
99 | }
100 | }
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/components/UI/Loading/Loading.js:
--------------------------------------------------------------------------------
1 | import "./Loading.scss";
2 |
3 | import star_full from "../../../assets/img/star.png";
4 | import star_none from "../../../assets/img/star_none.png";
5 | import { useEffect, useRef, useState } from "react";
6 | import Refund from "../Refund/Refund";
7 |
8 | const starArray = [0, 1, 2, 3, 4, 5];
9 |
10 | export const Loading = ({ title, onClickRefund, roomName }) => {
11 | const [currentTime, setCurrentTime] = useState(0);
12 | const [refund, setRefund] = useState(false);
13 | const timeInterval = useRef(0);
14 |
15 | useEffect(() => {
16 | timeInterval.current = setInterval(() => {
17 | setCurrentTime((prev) => prev + 1);
18 | if (currentTime > 10) {
19 | if(roomName != "Classic Room") setRefund(true);
20 | setCurrentTime(0);
21 | }
22 | }, 1000);
23 |
24 | return () => clearInterval(timeInterval.current);
25 | });
26 |
27 | return (
28 |
29 |
30 |
31 | {starArray.map((item, idx) => (
32 |
40 | ))}
41 |
42 |
45 |
46 |
setRefund(false)}
50 | onClickRefund={onClickRefund}
51 | >
52 |
53 | );
54 | };
55 | export default Loading;
56 |
--------------------------------------------------------------------------------
/src/components/UI/Loading/Loading.scss:
--------------------------------------------------------------------------------
1 | .loading {
2 | background-image: url("../../../assets/img/modal_back.png");
3 | background-size: 100% 100%;
4 | background-repeat: no-repeat;
5 | position: fixed;
6 | top: 0;
7 | left: 0;
8 | width: 100%;
9 | height: 100%;
10 | display: grid;
11 | align-items: center;
12 |
13 | &__container {
14 | position: absolute;
15 | transform: translate3d(-50%, -50%, 0);
16 | left: 50%;
17 | top: 50%;
18 | }
19 |
20 | &__stars {
21 | display: flex;
22 | align-items: center;
23 | justify-content: center;
24 |
25 | background: rgb(0, 0, 0, 0.2);
26 | border-radius: 20px;
27 | padding: 20px;
28 |
29 | img {
30 | width: 120px;
31 | padding: 0 5px;
32 | }
33 | }
34 |
35 | &__title {
36 | text-align: center;
37 |
38 | font: normal normal bold 68px Haettenschweiler;
39 | letter-spacing: 3px;
40 | color: #f9f8cb;
41 | font-family: Haettenschweiler;
42 | font-weight: 500;
43 |
44 | padding: 10px 0;
45 | }
46 | }
47 |
48 | @media (max-width: 1440px) {
49 | .loading {
50 | &__stars {
51 | border-radius: 1.39vw;
52 | padding: 1.39vw;
53 |
54 | img {
55 | width: 8.33vw;
56 | padding: 0 0.35vw;
57 | }
58 | }
59 |
60 | &__title {
61 | letter-spacing: 0.2vw;
62 | font-size: 4vw;
63 |
64 | padding: 0.7vw 0;
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/components/UI/Logo/Logo.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import logoPng from "../../../assets/img/logo.png";
4 | import "./Logo.scss";
5 |
6 | export default class Logo extends Component {
7 | render() {
8 | return (
9 |
10 |
11 |
12 | );
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/components/UI/Logo/Logo.scss:
--------------------------------------------------------------------------------
1 | .logo {
2 | position: relative;
3 | width: 100%;
4 | height: 100%;
5 | background-color: #00000087;
6 |
7 | img {
8 | position: relative;
9 | width: 50%;
10 | transform: translate3d(-50%, -50%, 0);
11 | left: 50%;
12 | top: 50%;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/components/UI/Loser/Loser.js:
--------------------------------------------------------------------------------
1 | import { Modal } from "react-bootstrap";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import "./Loser.scss";
4 | import Ranking from "../Ranking/Ranking";
5 | import { useState } from "react";
6 |
7 | export const Loser = ({ show, msg, onClickDrawHome }) => {
8 | const [ranking, setRanking] = useState(false);
9 | const [loading, setLoading] = useState(false);
10 |
11 | const onClickHome = () => {
12 | if(loading) return;
13 | onClickDrawHome();
14 | setLoading(true);
15 | }
16 |
17 | return (
18 |
25 |
26 |
{msg}
27 |
28 |
32 | {loading ? "Loading..." : "Return Home"}
33 |
34 |
setRanking(true)}>Ranking
35 |
36 |
37 | setRanking(false)}>
38 |
39 | );
40 | };
41 |
42 | export default Loser;
43 |
--------------------------------------------------------------------------------
/src/components/UI/Loser/Loser.scss:
--------------------------------------------------------------------------------
1 | .Loser {
2 | font-family: "HaettenschweilerRegular";
3 | color: #fbfae2;
4 | .u-container {
5 | position: relative;
6 | width: 40vw;
7 | height: 30vw;
8 | margin: auto;
9 | background-image: url("../../../assets/img/back_bg.png");
10 | background-repeat: no-repeat;
11 | background-size: 100% 100%;
12 | .u-msg {
13 | height: 20vw;
14 | padding: 5vw;
15 | display: grid;
16 | text-align: center;
17 | align-items: center;
18 | font-size: 2vw;
19 | }
20 | .u-btn-group {
21 | position: absolute;
22 | bottom: 1vw;
23 | width: 100%;
24 | padding: 1vw;
25 | display: flex;
26 | justify-content: space-evenly;
27 | text-align: center;
28 | .u-btn-yes {
29 | display: grid;
30 | align-items: center;
31 | width: 13vw;
32 | height: 4vw;
33 | padding: 0.1vw 1vw;
34 | background-image: url("../../../assets/img/victory_button.png");
35 | background-repeat: no-repeat;
36 | background-size: 100% 100%;
37 | font-size: 2.5vw;
38 | -webkit-text-stroke: 0.05em #0d6c6e;
39 | cursor: pointer;
40 | &:active {
41 | font-size: 2.45vw;
42 | }
43 | }
44 | .u-btn-no {
45 | display: grid;
46 | align-items: center;
47 | width: 13vw;
48 | height: 4vw;
49 | padding: 0.1vw 1vw;
50 | background-image: url("../../../assets/img/victory_button.png");
51 | background-repeat: no-repeat;
52 | background-size: 100% 100%;
53 | font-size: 2.5vw;
54 | -webkit-text-stroke: 0.05em #0d6c6e;
55 | cursor: pointer;
56 | &:active {
57 | font-size: 2.45vw;
58 | }
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/components/UI/MatchPlayLogin/MatchPlayLogin.js:
--------------------------------------------------------------------------------
1 | import { useNavigate } from "react-router-dom";
2 |
3 | import "bootstrap/dist/css/bootstrap.min.css";
4 | import "./MatchPlayLogin.scss";
5 | import { gameModes } from "../../../utils/constant";
6 | import { useState } from "react";
7 |
8 | export const MatchPlayLogin = () => {
9 | const [name, setName] = useState('');
10 | const navigate = useNavigate();
11 |
12 | const createAction = () => {
13 | if( name === '' )
14 | return;
15 |
16 | navigate('/friendPlay/rooms', { state: { mode: gameModes['P2P'], username: name, friendMatch: false }});
17 |
18 | }
19 |
20 | return (
21 |
22 |
23 |
Match matching game
24 |
25 |
26 |
27 |
28 | setName(e.target.value)}
33 | onKeyDown={(e) => e.key === 'Enter' ? createAction() : null}
34 | />
35 |
36 |
37 |
38 | Play
39 |
40 |
41 |
42 |
43 | )
44 | }
45 |
46 | export default MatchPlayLogin;
--------------------------------------------------------------------------------
/src/components/UI/MatchPlayLogin/MatchPlayLogin.scss:
--------------------------------------------------------------------------------
1 | .MatchPlayLogin {
2 | background-image: url("../../../assets/img/modal_back.png");
3 | background-size: 100% 100%;
4 | background-repeat: no-repeat;
5 | position: relative;
6 | height: 100%;
7 | display: grid;
8 | align-items: center;
9 |
10 | .u-container {
11 | position: relative;
12 | width: 70vw;
13 | height: calc(70vw * 0.6);
14 | top: 1vw;
15 | margin: auto;
16 | background-image: url("../../../assets/img/level_back.png");
17 | background-repeat: no-repeat;
18 | background-size: 100% 100%;
19 | text-align: center;
20 | vertical-align: middle;
21 |
22 | .u-ribbon {
23 | position: absolute;
24 | width: 60%;
25 | height: 6vw;
26 | left: 20%;
27 | top: -2.5vw;
28 | background-image: url("../../../assets/img/ribbon.png");
29 | background-repeat: no-repeat;
30 | background-size: 100% 100%;
31 | font-size: 3vw;
32 | text-align: center;
33 | font-family: Haettenschweiler, fantasy, Courier, monospace;
34 | color: #fbfae2;
35 | -webkit-text-stroke: 0.05em #792a4d;
36 | }
37 |
38 | .u-content {
39 | position: absolute;
40 | bottom: 0;
41 | width: 100%;
42 | height: calc(70vw * 0.6 - 3vw);
43 |
44 | .u-logo {
45 | position: absolute;
46 | margin: 1vw;
47 | width: 40%;
48 | height: 20vw;
49 | left: 30%;
50 | top: 0.5vw;
51 | background-image: url("../../../assets/img/logo.png");
52 | background-repeat: no-repeat;
53 | background-size: 100% 100%;
54 | }
55 |
56 | .u-input-wrap {
57 | margin-top: 20vw;
58 | padding: 1vw;
59 | height: 7vw;
60 | display: flex;
61 | justify-content: center;
62 | align-items: center;
63 |
64 | .u-input {
65 | text-align: center;
66 | background: url(../../../assets/img/inputbox.png);
67 | background-repeat: no-repeat;
68 | background-size: 100% 100%;
69 | width: 40%;
70 | height: 5vw;
71 | border-width: 0;
72 | border-radius: 2.5vw;
73 | font-size: 2vw;
74 | color: white;
75 | padding-left: 0.5em;
76 | font-family: Haettenschweiler, fantasy, Courier, monospace;
77 | }
78 |
79 | .u-input {
80 | outline: none;
81 | border: 0;
82 | }
83 | }
84 |
85 | .u-buttongroup {
86 | display: inline-grid;
87 | .u-button {
88 | text-align: center;
89 | align-items: center;
90 | background-image: url("../../../assets/img/victory_button.png");
91 | background-repeat: no-repeat;
92 | background-size: 100% 100%;
93 | width: 14vw;
94 | height: 5vw;
95 | border-radius: 100px;
96 | color: #f9f8cb;
97 | font-family: Haettenschweiler, fantasy, Courier, monospace;
98 | font-size: 2.5vw;
99 | background-color: transparent;
100 | border-color: transparent;
101 | text-shadow: -1px 1px 1px #0d6c6e, 1px 1px 1px #0d6c6e,
102 | 1px -1px 1px #0d6c6e, -1px -1px 1px #0d6c6e;
103 | }
104 |
105 | .u-button:active {
106 | font-size: 2.45vw;
107 | }
108 | }
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/components/UI/Orientation/Orientation.js:
--------------------------------------------------------------------------------
1 | import { Modal } from "react-bootstrap";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import "./Orientation.scss";
4 |
5 | export const Orientation = ({ show }) => {
6 | return (
7 |
14 |
15 |
Please convert to landscape mode.
16 |
17 |
18 | );
19 | };
20 |
21 | export default Orientation;
22 |
--------------------------------------------------------------------------------
/src/components/UI/Orientation/Orientation.scss:
--------------------------------------------------------------------------------
1 | .Orientation {
2 | font-family: "HaettenschweilerRegular";
3 | color: #fbfae2;
4 | .u-container {
5 | position: relative;
6 | width: 100vw;
7 | height: 100vh;
8 | margin: auto;
9 | background-color: #744349;
10 | display: grid;
11 | align-items: center;
12 | text-align: center;
13 | .u-msg {
14 | padding: 5vw;
15 | display: grid;
16 | text-align: center;
17 | align-items: center;
18 | font-size: 3vw;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/UI/PawnModal/PawnModal.js:
--------------------------------------------------------------------------------
1 | import { Modal } from "react-bootstrap";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import "./PawnModal.scss";
4 |
5 | import ICON_KNIGHT from "../../../assets/img/pawn_knight_icon.png";
6 | import ICON_BISHOP from "../../../assets/img/pawn_bishop_icon.png";
7 | import ICON_ROOK from "../../../assets/img/pawn_rook_icon.png";
8 | import ICON_QUEEN from "../../../assets/img/pawn_queen_icon.png";
9 | import BG_KNIGHT from "../../../assets/img/pawn_knight_bg.png";
10 | import BG_BISHOP from "../../../assets/img/pawn_bishop_bg.png";
11 | import BG_ROOK from "../../../assets/img/pawn_rook_bg.png";
12 | import BG_QUEEN from "../../../assets/img/pawn_queen_bg.png";
13 | import SYMBOL_KNIGHT from "../../../assets/img/pawn_knight_wolf.png";
14 | import SYMBOL_BISHOP from "../../../assets/img/pawn_bishop_cyborg.png";
15 | import SYMBOL_ROOK from "../../../assets/img/pawn_rook_dragon.png";
16 | import SYMBOL_QUEEN from "../../../assets/img/pawn_queen_medusa_fox.png";
17 | import { useState } from "react";
18 |
19 | const PAWN_ITEMS = [
20 | {
21 | type: "Knight",
22 | icon: ICON_KNIGHT,
23 | desc: "Cerberus",
24 | bg: BG_KNIGHT,
25 | symbol: SYMBOL_KNIGHT,
26 | width: "12vw",
27 | height: "13vw",
28 | top: "-4vw",
29 | },
30 | {
31 | type: "Bishop",
32 | icon: ICON_BISHOP,
33 | desc: "Keo502",
34 | bg: BG_BISHOP,
35 | symbol: SYMBOL_BISHOP,
36 | width: "9vw",
37 | height: "13vw",
38 | top: "-5.7vw",
39 | },
40 | {
41 | type: "Rook",
42 | icon: ICON_ROOK,
43 | desc: "Bahamut",
44 | bg: BG_ROOK,
45 | symbol: SYMBOL_ROOK,
46 | width: "14vw",
47 | height: "12vw",
48 | top: "-4vw",
49 | },
50 | {
51 | type: "Queen",
52 | icon: ICON_QUEEN,
53 | desc: "Medusa/Sakura",
54 | bg: BG_QUEEN,
55 | symbol: SYMBOL_QUEEN,
56 | width: "12vw",
57 | height: "13vw",
58 | top: "-5.7vw",
59 | }
60 | ];
61 |
62 | export const PawnModal = ({ show, pawnTransform }) => {
63 | const [currentPiece, setCurrentPiece] = useState(null);
64 |
65 | return (
66 |
73 |
74 |
75 | Your Pawn has reach the endpoint, please choose a Character to transform
76 |
77 |
78 | {
79 | PAWN_ITEMS.map((item, index) => (
80 |
setCurrentPiece(item.type)}>
81 |
82 |
83 |
84 |
85 |
{item.type}
86 |
87 |
{item.desc}
88 |
89 |
90 | ))
91 | }
92 |
93 |
pawnTransform(currentPiece)}>
94 | Confirm
95 |
96 |
97 |
98 | );
99 | }
100 |
101 | export default PawnModal;
--------------------------------------------------------------------------------
/src/components/UI/PawnModal/PawnModal.scss:
--------------------------------------------------------------------------------
1 | @keyframes pawnPieceAnim {
2 | 0% {
3 | transform: scale(1);
4 | }
5 | 50% {
6 | transform: scale(1.1);
7 | }
8 | 100% {
9 | transform: scale(1);
10 | }
11 | }
12 |
13 | .pawn {
14 | background-image: url("../../../assets/img/1v1_back.png");
15 | background-repeat: no-repeat;
16 | background-size: 100% 100%;
17 | width: 78vw;
18 | height: calc(70vw * 0.6);
19 | position: absolute;
20 | display: flex;
21 | justify-content: flex-start;
22 | flex-direction: column;
23 | align-items: center;
24 | padding: 3.5vw 3.5vw;
25 | transform: translate3d(-50%, -50%, 0);
26 | left: 50%;
27 | top: 0;
28 |
29 | &-desc {
30 | width: 100%;
31 | font-size: 1.5vw;
32 | font-family: Arial, Helvetica, sans-serif;
33 | color: #fdf9e8;
34 | text-align: center;
35 | background-color: #20122466;
36 | border-radius: 2vw;
37 | padding: 1vw 2vw;
38 | height: fit-content;
39 | line-height: 1.3;
40 | }
41 |
42 | &-cards {
43 | margin-top: 3vw;
44 | display: flex;
45 | flex-wrap: wrap;
46 | justify-content: center;
47 | width: 100%;
48 | align-items: flex-start;
49 | }
50 |
51 | &-card {
52 | width: 22%;
53 | margin: 2.5vw 1vw;
54 | position: relative;
55 | height: 18.5vw;
56 | background-size: 100% 100%;
57 | display: flex;
58 | justify-content: center;
59 | transition: all 0.25s;
60 |
61 | &:hover {
62 | cursor: pointer;
63 | }
64 |
65 | &.active {
66 | animation: pawnPieceAnim 0.5s linear infinite;
67 | }
68 |
69 | &-symbol-image {
70 | position: absolute;
71 | background-size: 100% 100%;
72 | }
73 |
74 | &-content {
75 | display: flex;
76 | flex-direction: column;
77 | align-items: center;
78 | margin-top: 9vw;
79 | &-header {
80 | display: flex;
81 | flex-direction: row;
82 | justify-content: space-between;
83 | align-items: center;
84 |
85 | &-icon {
86 | width: 1.7vw;
87 | height: 1.7vw;
88 | margin-right: 1vw;
89 | }
90 |
91 | &-title {
92 | font-size: 2vw;
93 | color: #f7cf29;
94 | font-family: "HaettenschweilerRegular";
95 | letter-spacing: 0.02em;
96 | line-height: 1;
97 | }
98 | }
99 |
100 | &-desc {
101 | margin-top: 2.5vw;
102 | font-size: 2vw;
103 | color: white;
104 | font-family: "HaettenschweilerRegular";
105 | letter-spacing: 0.02em;
106 | line-height: 1;
107 | }
108 | }
109 | }
110 |
111 | &-button {
112 | margin-top: 1.5vw;
113 | background-image: url("../../../assets/img/confirm_btn_bg.png");
114 | background-repeat: no-repeat;
115 | background-size: 100% 100%;
116 | width: 14vw;
117 | height: 3.6vw;
118 | cursor: pointer;
119 | text-align: center;
120 | color: #f9f8cb;
121 | font-size: 2vw;
122 | font-family: "HaettenschweilerRegular";
123 | letter-spacing: 0.01em;
124 | line-height: 1.3;
125 | text-shadow: 1px 1px 0 #0c6c6d, -1px 1px 0 #0c6c6d, 1px -1px 0 #0c6c6d,
126 | -1px -1px 0 #0c6c6d, 0px 1px 0 #0c6c6d, 0px -1px 0 #0c6c6d,
127 | -1px 0px 0 #0c6c6d, 1px 0px 0 #0c6c6d, 2px 2px 0 #0c6c6d,
128 | -2px 2px 0 #0c6c6d, 2px -2px 0 #0c6c6d, -2px -2px 0 #0c6c6d,
129 | 0px 2px 0 #0c6c6d, 0px -2px 0 #0c6c6d, -2px 0px 0 #0c6c6d,
130 | 2px 0px 0 #0c6c6d, 1px 2px 0 #0c6c6d, -1px 2px 0 #0c6c6d,
131 | 1px -2px 0 #0c6c6d, -1px -2px 0 #0c6c6d, 2px 1px 0 #0c6c6d,
132 | -2px 1px 0 #0c6c6d, 2px -1px 0 #0c6c6d, -2px -1px 0 #0c6c6d;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/components/UI/Play2Earn/Play2Earn.js:
--------------------------------------------------------------------------------
1 | import "bootstrap/dist/css/bootstrap.min.css";
2 | import "./Play2Earn.scss";
3 | import { useNavigate } from "react-router-dom";
4 |
5 | export const Play2Earn = () => {
6 | const navigate = useNavigate();
7 |
8 | return (
9 |
10 |
11 |
Play2Earn
12 |
13 |
14 |
15 |
16 | navigate('/friendPlay/create') }>Create Game
17 | navigate('/friendPlay/join') }>Join Game
18 |
19 |
20 |
21 |
22 | );
23 | }
24 |
25 | export default Play2Earn;
--------------------------------------------------------------------------------
/src/components/UI/Play2Earn/Play2Earn.scss:
--------------------------------------------------------------------------------
1 | .playToEarn {
2 | background-image: url("../../../assets/img/modal_back.png");
3 | background-size: 100% 100%;
4 | background-repeat: no-repeat;
5 | position: relative;
6 | height: 100%;
7 | display: grid;
8 | align-items: center;
9 |
10 | .u-container {
11 | position: relative;
12 | width: 70vw;
13 | height: calc(70vw * 0.6);
14 | top: 1vw;
15 | margin: auto;
16 | background-image: url("../../../assets/img/level_back.png");
17 | background-repeat: no-repeat;
18 | background-size: 100% 100%;
19 | text-align: center;
20 | vertical-align: middle;
21 |
22 | .u-ribbon {
23 | position: absolute;
24 | width: 60%;
25 | height: 6vw;
26 | left: 20%;
27 | top: -2.5vw;
28 | background-image: url("../../../assets/img/ribbon.png");
29 | background-repeat: no-repeat;
30 | background-size: 100% 100%;
31 | font-size: 3vw;
32 | text-align: center;
33 | font-family: Haettenschweiler, fantasy, Courier, monospace;
34 | color: #fbfae2;
35 | -webkit-text-stroke: 0.05em #792a4d;
36 | }
37 |
38 | .u-content {
39 | position: absolute;
40 | bottom: 0;
41 | width: 100%;
42 | height: calc(70vw * 0.6 - 3vw);
43 |
44 | .u-logo {
45 | position: absolute;
46 | width: 40%;
47 | height: 20vw;
48 | left: 30%;
49 | top: 0.5vw;
50 | background-image: url("../../../assets/img/logo.png");
51 | background-repeat: no-repeat;
52 | background-size: 100% 100%;
53 | }
54 | .u-buttongroup {
55 | display: inline-grid;
56 | margin-top: 19vw;
57 | .u-button {
58 | margin-top: 2vw;
59 | text-align: center;
60 | align-items: center;
61 | background-image: url("../../../assets/img/victory_button.png");
62 | background-repeat: no-repeat;
63 | background-size: 100% 100%;
64 | width: 14vw;
65 | height: 5vw;
66 | border-radius: 100px;
67 | color: #f9f8cb;
68 | font-family: Haettenschweiler, fantasy, Courier, monospace;
69 | font-size: 2.5vw;
70 | background-color: transparent;
71 | border-color: transparent;
72 | text-shadow: -1px 1px 1px #0d6c6e, 1px 1px 1px #0d6c6e,
73 | 1px -1px 1px #0d6c6e, -1px -1px 1px #0d6c6e;
74 | }
75 |
76 | .u-button:active {
77 | font-size: 2.45vw;
78 | }
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/components/UI/Popup/Popup.js:
--------------------------------------------------------------------------------
1 | import { Modal } from "react-bootstrap";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import "./Popup.scss";
4 |
5 | export const Popup = ({ show, type, message, agreeAction, disAgreeAction }) => {
6 | return (
7 |
14 |
15 |
16 | { message }
17 |
18 |
19 | {
20 | type === 'leaveNotification' ?
21 |
window.location = '/'}>Return
: null
22 | }
23 |
24 | {
25 | type === 'drawRequest' ? (
26 | <>
27 |
Yes
28 |
No
29 | >
30 | ) : null
31 | }
32 |
33 |
34 |
35 | );
36 | }
37 |
38 | export default Popup;
--------------------------------------------------------------------------------
/src/components/UI/Popup/Popup.scss:
--------------------------------------------------------------------------------
1 | .Popup {
2 | display: grid !important;
3 | align-items: center;
4 |
5 | .form {
6 | width: 47vw;
7 | height: calc(70vw * 0.5);
8 | background-image: url("../../../assets/img/back_bg.png");
9 | background-repeat: no-repeat;
10 | background-size: 100% 100%;
11 | position: relative;
12 | transform: translate3d(-50%, -50%, 0);
13 | left: 50%;
14 | top: calc(70vw * 0.25);
15 |
16 | .content {
17 | text-align: left;
18 | font-family: "HaettenschweilerRegular";
19 | letter-spacing: 0.01em;
20 | color: #f9f8cb;
21 | font-size: 2vw;
22 | vertical-align: middle;
23 | padding: 0 10%;
24 | position: relative;
25 | transform: translateY(-50%);
26 | top: 42%;
27 | text-align: center;
28 | }
29 | .footer {
30 | position: absolute;
31 | bottom: 3vw;
32 | display: flex;
33 | width: 100%;
34 | padding: 0 3vw;
35 | justify-content: space-between;
36 |
37 | &.center {
38 | justify-content: center;
39 | }
40 |
41 | .button-div {
42 | cursor: pointer;
43 | margin: 0 1.5vw;
44 | padding: 0 1.5vw;
45 | background-image: url("../../../assets/img/blue_button_bg.png");
46 | background-repeat: no-repeat;
47 | background-size: 100% 100%;
48 | height: 5vw;
49 | text-align: center;
50 | color: #f9f8cb;
51 | font-size: 3.5vw;
52 | font-family: "HaettenschweilerRegular";
53 | letter-spacing: 0.01em;
54 | line-height: 1.25;
55 | text-shadow: 1px 1px 0 #0c6c6d, -1px 1px 0 #0c6c6d, 1px -1px 0 #0c6c6d,
56 | -1px -1px 0 #0c6c6d, 0px 1px 0 #0c6c6d, 0px -1px 0 #0c6c6d,
57 | -1px 0px 0 #0c6c6d, 1px 0px 0 #0c6c6d, 2px 2px 0 #0c6c6d,
58 | -2px 2px 0 #0c6c6d, 2px -2px 0 #0c6c6d, -2px -2px 0 #0c6c6d,
59 | 0px 2px 0 #0c6c6d, 0px -2px 0 #0c6c6d, -2px 0px 0 #0c6c6d,
60 | 2px 0px 0 #0c6c6d, 1px 2px 0 #0c6c6d, -1px 2px 0 #0c6c6d,
61 | 1px -2px 0 #0c6c6d, -1px -2px 0 #0c6c6d, 2px 1px 0 #0c6c6d,
62 | -2px 1px 0 #0c6c6d, 2px -1px 0 #0c6c6d, -2px -1px 0 #0c6c6d;
63 | }
64 | .button-div:active {
65 | font-size: 3.45vw;
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/components/UI/Ranking/Ranking.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable array-callback-return */
2 | import { Component } from "react";
3 | import RankingRow from "./RankingRow";
4 | import "./Ranking.scss";
5 | import axios from "axios";
6 | import { socketServerPort } from "../../../config";
7 | import { Modal } from "react-bootstrap";
8 |
9 | export default class Ranking extends Component {
10 | // eslint-disable-next-line no-useless-constructor
11 | constructor(props) {
12 | super(props);
13 | }
14 |
15 | componentDidMount() {
16 | axios
17 | .post(
18 | `http://${window.location.hostname}:${socketServerPort}/api/rankAll`
19 | )
20 | .then((res) => {
21 | let rankData = [...res.data.rankData];
22 | rankData.sort((a, b) => {
23 | if ( (b.won - b.lost) > (a.won - a.lost) ) {
24 | return 1;
25 | } else if ( (b.won - b.lost) < (a.won - a.lost) ) {
26 | return -1;
27 | } else {
28 | return b.won - a.won;
29 | }
30 | });
31 |
32 | this.setState({
33 | rankData,
34 | });
35 |
36 | console.log(this.state.rankData);
37 | });
38 | }
39 |
40 | render() {
41 | return (
42 |
49 |
50 |
Ranking Table
51 |
52 |
53 |
Rank
54 |
User name
55 |
matches won/loss
56 |
LLG earn
57 |
58 |
59 | {this.state && this.state.rankData
60 | ? this.state.rankData.map((item, index) => {
61 | const info = {
62 | name: item.username,
63 | won: `${item.won} / ${item.lost}`,
64 | earn: item.earn,
65 | key: index,
66 | index: index,
67 | };
68 |
69 | return ;
70 | })
71 | : null}
72 |
73 |
74 |
Back
75 |
76 |
77 | );
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/components/UI/Ranking/Ranking.scss:
--------------------------------------------------------------------------------
1 | .ranking {
2 | position: relative;
3 | text-align: center;
4 | width: 70vw;
5 | height: 90vh;
6 | font-family: "HaettenschweilerRegular";
7 | background-image: url("../../../assets/img/back_bg.png");
8 | background-repeat: no-repeat;
9 | background-size: 100% 100%;
10 | color: #fbfae2;
11 | * {
12 | margin: auto;
13 | }
14 | &-title {
15 | width: 40vw;
16 | height: 8vw;
17 | text-align: center;
18 | background-image: url("../../../assets/img/ribbon.png");
19 | background-repeat: no-repeat;
20 | background-size: 100% 100%;
21 | margin: 2vw auto 1vw auto;
22 | font-size: 4.5vw;
23 | -webkit-text-stroke: 0.05em #792a4d;
24 | }
25 | &-table {
26 | margin: 1vw auto;
27 | width: 60vw;
28 | height: calc(90vh - 19vw);
29 | overflow: hidden;
30 | border-radius: 0.5vw;
31 | outline: 0.2vw solid #110919;
32 | background-color: rgba($color: #311437, $alpha: 0.39);
33 | &-head {
34 | background-color: rgba($color: #3c183c, $alpha: 0.62);
35 | outline: 1px solid #0e0616;
36 | border-radius: 0.5vw;
37 | color: #ecbc6a;
38 | -webkit-text-stroke: #0c6c6d;
39 | font-size: 2vw;
40 | display: flex;
41 | height: 3vw;
42 | &-rank {
43 | width: 15vw;
44 | }
45 | &-name {
46 | width: 17vw;
47 | }
48 | &-won {
49 | width: 17vw;
50 | }
51 | &-earn {
52 | width: 9vw;
53 | }
54 | }
55 | &-body {
56 | margin: 0.4vw 3vw;
57 | border: 0.1vw solid #a8728b;
58 | border-radius: 1vw;
59 | background-color: rgba($color: #321830, $alpha: 0.59);
60 | height: calc(100% - 4vw);
61 | font-size: 1.5vw;
62 | color: #f8edc3;
63 | font-family: Arial;
64 | overflow: auto;
65 | &::-webkit-scrollbar {
66 | width: 0.4vw;
67 | }
68 | &::-webkit-scrollbar-track {
69 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
70 | border-radius: 0.2vw;
71 | }
72 | &::-webkit-scrollbar-thumb {
73 | background-color: rgba($color: black, $alpha: 0.4);
74 | outline: 1px solid rgba($color: black, $alpha: 0.4);
75 | border-radius: 0.2vw;
76 | }
77 | &-row {
78 | display: flex;
79 | border-bottom: 0.1vw solid #ad8494;
80 | * {
81 | display: grid;
82 | align-items: center;
83 | }
84 | &-rank {
85 | width: 12vw;
86 | &-img {
87 | height: 3vw;
88 | }
89 | }
90 | &-name {
91 | padding: 0.5vw 0;
92 | width: 17vw;
93 | }
94 | &-won {
95 | width: 17vw;
96 | }
97 | &-earn {
98 | width: 6vw;
99 | }
100 | }
101 | }
102 | }
103 | &-btn_choose {
104 | width: 25vw;
105 | height: 5vw;
106 | display: grid;
107 | align-items: center;
108 | text-align: center;
109 | background-image: url("../../../assets/img/victory_button.png");
110 | background-repeat: no-repeat;
111 | background-size: 100% 100%;
112 | margin: 1vw auto 2vw auto;
113 | font-size: 3vw;
114 | -webkit-text-stroke: 0.05em #0c6c6d;
115 | cursor: pointer;
116 | &:active {
117 | font-size: 2.95vw;
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/components/UI/Ranking/RankingRow.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable array-callback-return */
2 | import { Component } from "react";
3 | import { Image } from "react-bootstrap";
4 | import rank1 from "../../../assets/img/ranking/1.png";
5 | import rank2 from "../../../assets/img/ranking/2.png";
6 | import rank3 from "../../../assets/img/ranking/3.png";
7 |
8 | export default class Ranking extends Component {
9 | // eslint-disable-next-line no-useless-constructor
10 | constructor(props) {
11 | super(props);
12 | this.arrImg = [rank1, rank2, rank3];
13 | }
14 |
15 | addressFormat( string ) {
16 | if( !string )
17 | return '';
18 |
19 | return string.slice(0, 7) + '...' + string.slice( string.length - 7, string.length );
20 | }
21 |
22 | render() {
23 | return (
24 |
25 |
26 | {this.props.index < 3 ? (
27 |
31 | ) : (
32 | this.props.index + 1
33 | )}
34 |
35 |
{ this.addressFormat(this.props.name) }
36 |
{this.props.won}
37 |
{this.props.earn}
38 |
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/components/UI/Refund/Refund.js:
--------------------------------------------------------------------------------
1 | import { Modal } from "react-bootstrap";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import "./Refund.scss";
4 |
5 | export const Refund = ({ show, msg, hideAction, onClickRefund }) => {
6 | return (
7 |
14 |
15 |
{msg}
16 |
17 |
Refund
18 |
Keep finding
19 |
20 |
21 |
22 | );
23 | };
24 |
25 | export default Refund;
26 |
--------------------------------------------------------------------------------
/src/components/UI/Refund/Refund.scss:
--------------------------------------------------------------------------------
1 | .refund {
2 | font-family: "HaettenschweilerRegular";
3 | color: #fbfae2;
4 | &-container {
5 | position: relative;
6 | width: 40vw;
7 | height: 30vw;
8 | margin: auto;
9 | background-image: url("../../../assets/img/back_bg.png");
10 | background-repeat: no-repeat;
11 | background-size: 100% 100%;
12 | &-msg {
13 | height: 25vw;
14 | padding: 5vw;
15 | display: grid;
16 | text-align: center;
17 | align-items: center;
18 | font-size: 2vw;
19 | }
20 | &-btn_group {
21 | position: absolute;
22 | bottom: 1vw;
23 | width: 100%;
24 | padding: 1vw;
25 | display: flex;
26 | justify-content: space-evenly;
27 | text-align: center;
28 | &-yes {
29 | display: grid;
30 | align-items: center;
31 | width: 15vw;
32 | padding: 0.1vw 1vw;
33 | background-image: url("../../../assets/img/victory_button.png");
34 | background-repeat: no-repeat;
35 | background-size: 100% 100%;
36 | font-size: 2.5vw;
37 | -webkit-text-stroke: 0.05em #0d6c6e;
38 | cursor: pointer;
39 | &:active {
40 | font-size: 2.45vw;
41 | }
42 | }
43 | &-no {
44 | display: grid;
45 | align-items: center;
46 | width: 15vw;
47 | padding: 0.1vw 1vw;
48 | background-image: url("../../../assets/img/victory_button.png");
49 | background-repeat: no-repeat;
50 | background-size: 100% 100%;
51 | font-size: 2.5vw;
52 | -webkit-text-stroke: 0.05em #0d6c6e;
53 | cursor: pointer;
54 | &:active {
55 | font-size: 2.45vw;
56 | }
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/components/UI/RoomsScreen/RoomsScreen.js:
--------------------------------------------------------------------------------
1 | import { useNavigate, useLocation } from "react-router-dom";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import "./RoomsScreen.scss";
4 |
5 | import { gameModes } from "../../../utils/constant";
6 |
7 | import ICON_CLASSIC from "../../../assets/img/1v1_classic_header.png";
8 | import ICON_SILVER from "../../../assets/img/1v1_silver_header.png";
9 | import ICON_GOLD from "../../../assets/img/1v1_gold_header.png";
10 | import ICON_PLATINUM from "../../../assets/img/1v1_platinum_header.png";
11 | import ICON_DIAMOND from "../../../assets/img/1v1_diamond_header.png";
12 | import BG_CLASSIC from "../../../assets/img/1v1_classic_bg.png";
13 | import BG_SILVER from "../../../assets/img/1v1_silver_bg.png";
14 | import BG_GOLD from "../../../assets/img/1v1_gold_bg.png";
15 | import BG_PLATINUM from "../../../assets/img/1v1_platinum_bg.png";
16 | import BG_DIAMOND from "../../../assets/img/1v1_diamond_bg.png";
17 | import { useEffect, useState } from "react";
18 | import io from 'socket.io-client';
19 | import { socketServerPort } from "../../../config";
20 | import { socketEvents } from "../../../utils/packet";
21 | import store from "../../../store/store";
22 |
23 | const ROOMS = [
24 | {
25 | name: "Classic Room",
26 | pool: "Pool: No rewards",
27 | desc: "Players can play for free 1v1 against another player",
28 | icon: ICON_CLASSIC,
29 | bg: BG_CLASSIC,
30 | },
31 | {
32 | name: "Silver Room",
33 | pool: "Pool: 98 $LLG",
34 | desc: "Each player needs to put in 50 $LLG",
35 | icon: ICON_SILVER,
36 | bg: BG_SILVER,
37 | },
38 | {
39 | name: "Gold Room",
40 | pool: "Pool: 198 $LLG",
41 | desc: "Each player needs to put in 100 $LLG",
42 | icon: ICON_GOLD,
43 | bg: BG_GOLD,
44 | },
45 | {
46 | name: "Platinum Room",
47 | pool: "Pool: 392 $LLG",
48 | desc: "Each player needs to put in 200 $LLG",
49 | icon: ICON_PLATINUM,
50 | bg: BG_PLATINUM,
51 | },
52 | {
53 | name: "Diamond Room",
54 | pool: "Pool: 980 $LLG",
55 | desc: "Each player needs to put in 500 $LLG",
56 | icon: ICON_DIAMOND,
57 | bg: BG_DIAMOND,
58 | }
59 | ];
60 |
61 | const RoomsScreen = () => {
62 | const navigate = useNavigate();
63 | const { state } = useLocation();
64 | const [ socket, setSocket ] = useState();
65 |
66 | const updateSocket = store( state => state.updateSocket );
67 |
68 | const onClickRoom = (roomName) => {
69 | if( roomName !== 'Classic Room' )
70 | return;
71 |
72 | const data = {};
73 | data.roomName = roomName;
74 | data.username = state.username;
75 | data.friendMatch = state.friendMatch;
76 |
77 | if( !state.friendMatch ) {
78 | socket.emit( socketEvents['CS_MatchPlayLogin'], data );
79 |
80 | // const stateData = {
81 | // mode: gameModes['P2P'],
82 | // friendMatch: state.friendMatch,
83 | // username: state.username,
84 | // roomName: roomName,
85 | // }
86 |
87 | // if (roomName === 'Classic Room') {
88 | // navigate('/gameScene', { state: { ...stateData } });
89 | // } else {
90 | // navigate('/connect', { state: { ...stateData } });
91 | // }
92 | } else {
93 | socket.emit( socketEvents['CS_CreateRoom'], data );
94 | }
95 | }
96 |
97 | const handleRoomCreated = (params) => {
98 | const { roomId, roomName, roomKey } = params;
99 |
100 | const stateData = {
101 | mode: gameModes['P2P'],
102 | friendMatch: state.friendMatch,
103 | username: state.username,
104 | roomName: roomName,
105 | roomId: roomId,
106 | roomKey: roomKey,
107 | }
108 |
109 | if (roomName === 'Classic Room' && state.friendMatch === true) {
110 | navigate('/gameScene', { state: { ...stateData } });
111 | } else {
112 | navigate('/connect', { state: { ...stateData } });
113 | }
114 | }
115 |
116 | useEffect(() => {
117 | const skt = io.connect(`http://${window.location.hostname}:${socketServerPort}`);
118 | setSocket( skt );
119 |
120 | skt.on( socketEvents['SC_RoomCreated'], (params) => handleRoomCreated(params) );
121 |
122 | updateSocket( skt );
123 | }, []);
124 |
125 | return (
126 |
129 |
130 |
1 VS 1 MODE
131 |
132 |
There are 5 different rooms. Two players each put in the specified amount of LLG (based on the room type) into a pool. After each game, whoever wins the game takes all the LLG in the pool.
133 |
134 | {
135 | ROOMS.map((room, index) => (
136 |
onClickRoom(room.name)}>
137 |
138 |
139 |
{room.name}
140 |
{room.pool}
141 |
{room.desc}
142 |
143 |
144 | ))
145 | }
146 |
147 |
148 |
149 |
150 | );
151 | }
152 |
153 | export default RoomsScreen;
154 |
--------------------------------------------------------------------------------
/src/components/UI/RoomsScreen/RoomsScreen.scss:
--------------------------------------------------------------------------------
1 | .rooms {
2 | background-image: url("../../../assets/img/modal_back.png");
3 | background-size: 100% 100%;
4 | background-repeat: no-repeat;
5 | position: relative;
6 | height: 100%;
7 | display: flex;
8 | justify-content: center;
9 | align-items: center;
10 |
11 | &-container {
12 | background-image: url("../../../assets/img/1v1_back.png");
13 | background-repeat: no-repeat;
14 | background-size: 100% 100%;
15 | width: 78vw;
16 | height: calc(70vw * 0.6);
17 | position: relative;
18 | display: flex;
19 | justify-content: center;
20 | padding: 3.5vw 3.5vw;
21 | &-header {
22 | background-image: url("../../../assets/img/1v1_header.png");
23 | background-repeat: no-repeat;
24 | background-size: 100% 100%;
25 | border-width: 0;
26 | background-color: transparent;
27 | position: absolute;
28 | top: -2.3vw;
29 | width: 16vw;
30 | height: 5vw;
31 | text-align: center;
32 | vertical-align: middle;
33 | line-height: 1.7;
34 | font-size: 3vw;
35 | font-family: "HaettenschweilerRegular";
36 | color: #f9f8cb;
37 | letter-spacing: 0.025em;
38 | text-shadow: 1px 1px 0 #0c6c6d, -1px 1px 0 #0c6c6d, 1px -1px 0 #0c6c6d,
39 | -1px -1px 0 #0c6c6d, 0px 1px 0 #0c6c6d, 0px -1px 0 #0c6c6d,
40 | -1px 0px 0 #0c6c6d, 1px 0px 0 #0c6c6d, 2px 2px 0 #0c6c6d,
41 | -2px 2px 0 #0c6c6d, 2px -2px 0 #0c6c6d, -2px -2px 0 #0c6c6d,
42 | 0px 2px 0 #0c6c6d, 0px -2px 0 #0c6c6d, -2px 0px 0 #0c6c6d,
43 | 2px 0px 0 #0c6c6d, 1px 2px 0 #0c6c6d, -1px 2px 0 #0c6c6d,
44 | 1px -2px 0 #0c6c6d, -1px -2px 0 #0c6c6d, 2px 1px 0 #0c6c6d,
45 | -2px 1px 0 #0c6c6d, 2px -1px 0 #0c6c6d, -2px -1px 0 #0c6c6d;
46 | }
47 | &-content {
48 | margin-top: 0.5vw;
49 | display: flex;
50 | justify-content: flex-start;
51 | flex-direction: column;
52 | align-items: center;
53 | &-desc {
54 | font-size: 1.5vw;
55 | font-family: Haettenschweiler, fantasy, Courier, monospace;
56 | color: #fdf9e8;
57 | text-align: center;
58 | background-color: #20122466;
59 | border-radius: 2vw;
60 | padding: 1vw 1.5vw;
61 | height: fit-content;
62 | line-height: 1.3;
63 | margin-bottom: 0 !important;
64 | }
65 | &-rooms {
66 | margin-top: 2.8vw;
67 | display: flex;
68 | flex-wrap: wrap;
69 | justify-content: center;
70 | width: 100%;
71 | align-items: flex-start;
72 | }
73 | &-room {
74 | width: 28%;
75 | margin: 1.5vw;
76 | position: relative;
77 | height: 11vw;
78 | background-size: 100% 100%;
79 | display: flex;
80 | justify-content: center;
81 | cursor: pointer;
82 |
83 | &.closed {
84 | &::after {
85 | content: "";
86 | width: 6vw;
87 | height: 6vw;
88 | background-image: url('../../../assets/img/coming-soon.png');
89 | background-repeat: no-repeat;
90 | background-size: cover;
91 | position: absolute;
92 | right: 0;
93 | top: 0;
94 | }
95 | }
96 |
97 | &-icon {
98 | position: absolute;
99 | background-size: 100% 100%;
100 | width: 9.8vw;
101 | height: 9vw;
102 | top: -4vw;
103 | }
104 |
105 | &-texts {
106 | margin-top: 3vw;
107 | display: flex;
108 | flex-direction: column;
109 | align-items: center;
110 | }
111 | &-name {
112 | font-size: 2vw;
113 | color: #f7cf29;
114 | font-family: "HaettenschweilerRegular";
115 | letter-spacing: 0.02em;
116 | line-height: 1;
117 | }
118 | &-pool {
119 | font-size: 1.9vw;
120 | color: white;
121 | font-family: "HaettenschweilerRegular";
122 | letter-spacing: 0.02em;
123 | line-height: 1;
124 | }
125 | &-desc {
126 | margin-top: 0.4vw;
127 | font-size: 1.1vw;
128 | font-weight: 400;
129 | color: white;
130 | font-family: Arial, Helvetica, sans-serif;
131 | line-height: 1.3;
132 | text-align: center;
133 | padding: 0 1.5vw;
134 | letter-spacing: 0.07em;
135 | }
136 | }
137 | }
138 | }
139 | }
140 |
141 | .modal-content {
142 | display: flex;
143 | justify-content: center;
144 | align-items: center;
145 | }
146 |
--------------------------------------------------------------------------------
/src/components/UI/Victory/Victory.js:
--------------------------------------------------------------------------------
1 | import { Modal, Image } from "react-bootstrap";
2 | import "bootstrap/dist/css/bootstrap.min.css";
3 | import "./Victory.scss";
4 | import backImg from "../../../assets/img/back_bg.png";
5 | import markImg from "../../../assets/img/victory_mark.png";
6 | import item1Img from "../../../assets/img/victory_item1.png";
7 | import item2Img from "../../../assets/img/victory_item2.png";
8 | import { useEffect, useState } from "react";
9 | import Ranking from "../Ranking/Ranking";
10 |
11 | export const Victory = ({ show, roomName, onClickLLGSymbol, tax }) => {
12 | const [loading, setLoading] = useState(false);
13 | const [llgToGetPaid, setLLGToGetPaid] = useState(0);
14 | const [llgDeposited, setLLGDeposited] = useState(0);
15 | const [ranking, setRanking] = useState(false);
16 |
17 | useEffect(() => {
18 | calcLLGs();
19 | });
20 |
21 | const onClick = () => {
22 | if (roomName == "Classic Room") window.location.href = "/";
23 | else {
24 | onClickLLGSymbol();
25 | setLoading(true);
26 | }
27 | };
28 |
29 | const calcLLGs = () => {
30 | switch (roomName) {
31 | case "Silver Room":
32 | setLLGToGetPaid(100);
33 | setLLGDeposited((100 * (100 - tax)) / 100);
34 | break;
35 | case "Gold Room":
36 | setLLGToGetPaid(200);
37 | setLLGDeposited((200 * (100 - tax)) / 100);
38 | break;
39 | case "Platinum Room":
40 | setLLGToGetPaid(400);
41 | setLLGDeposited((400 * (100 - tax)) / 100);
42 | break;
43 | case "Diamond Room":
44 | setLLGToGetPaid(1000);
45 | setLLGDeposited((1000 * (100 - tax)) / 100);
46 | break;
47 | }
48 | };
49 |
50 | return (
51 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
{llgToGetPaid}
67 |
68 |
69 |
70 |
{llgDeposited}
71 |
72 |
73 |
74 |
75 | {loading ? "Loading..." : "Return Home"}
76 |
77 | setRanking(true)}
81 | >
82 | Ranking
83 |
84 |
85 |
86 |
87 | setRanking(false)}>
88 |
89 |
90 | );
91 | };
92 |
93 | export default Victory;
94 |
--------------------------------------------------------------------------------
/src/components/UI/Victory/Victory.scss:
--------------------------------------------------------------------------------
1 | .Victory {
2 | display: grid;
3 | align-items: center;
4 |
5 | .u-container {
6 | width: 90vmin;
7 | height: 90vmin;
8 | margin: auto;
9 | position: relative;
10 |
11 | .u-background {
12 | width: 100%;
13 | height: 80%;
14 | bottom: 0;
15 | position: absolute;
16 | }
17 |
18 | .u-foreground {
19 | position: relative;
20 | width: 100%;
21 | height: 100%;
22 | text-align: center;
23 |
24 | .u-mark {
25 | width: 100%;
26 | height: 50%;
27 | }
28 |
29 | .u-list {
30 | padding: 0 5%;
31 | height: 35%;
32 |
33 | .u-list-item {
34 | padding: 0 10%;
35 | margin: 3%;
36 | height: 40%;
37 | display: flex;
38 | justify-content: space-between;
39 | background-image: url("../../../assets/img/victory_container.png");
40 | background-repeat: no-repeat;
41 | background-size: 100% 100%;
42 | align-items: center;
43 |
44 | .u-item-image {
45 | height: 90%;
46 | }
47 |
48 | .u-item-text {
49 | font-family: "HaettenschweilerRegular", fantasy, Courier, monospace;
50 | color: #f7cf29;
51 | font-size: 6vmin;
52 | -webkit-text-stroke: 0.05em #390b13;
53 | padding-right: 15%;
54 | }
55 | }
56 | }
57 |
58 | .u-btn-group {
59 | position: absolute;
60 | width: 100%;
61 | display: flex;
62 | align-items: center;
63 | text-align: center;
64 | justify-content: space-evenly;
65 | bottom: 4vmin;
66 |
67 | .u-button {
68 | text-align: center;
69 | align-items: center;
70 | background-image: url("../../../assets/img/victory_button.png");
71 | background-repeat: no-repeat;
72 | background-size: 100% 100%;
73 | width: 30vmin;
74 | border-radius: 100px;
75 | color: #f9f8cb;
76 | font-family: "HaettenschweilerRegular", fantasy, Courier, monospace;
77 | font-size: 4vmin;
78 | background-color: transparent;
79 | border-color: transparent;
80 | -webkit-text-stroke: 0.05em #0c6c6d;
81 | }
82 |
83 | .u-button:active {
84 | font-size: 3.95vmin;
85 | }
86 | }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/config/index.js:
--------------------------------------------------------------------------------
1 | export const apiServerPort = 8050;
2 |
3 | export const socketServerPort = 8050;
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
15 | body {
16 | overflow: hidden;
17 | }
18 |
19 | .modal-dialog {
20 | margin: 0 auto !important;
21 | max-width: 100% !important;
22 | }
23 |
24 | .modal-content {
25 | background-color: transparent !important;
26 | border-width: 0 !important;
27 | width: 100% !important;
28 | height: 100% !important;
29 | }
30 |
31 | .modal-dialog-centered {
32 | min-height: 100% !important;
33 | }
34 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/src/store/store.js:
--------------------------------------------------------------------------------
1 | import create from "zustand"
2 | import produce from "immer";
3 |
4 | const store = create(set => ({
5 | socket: null,
6 | updateSocket: ( val ) => set(produce(state => {
7 | state.socket = val;
8 | }))
9 | }))
10 |
11 | export default store;
--------------------------------------------------------------------------------
/src/utils/address.js:
--------------------------------------------------------------------------------
1 | export const llgContractAddress = "0x0e04Ad5f9a40ddfe82ac533C9D5284Fb3C72BcAa";
2 | export const llgRewardContractAddress = "0x9274011471a1Fac4fD5304fc1f8a536150057df7";
3 | export const chainId = 0x61;
--------------------------------------------------------------------------------
/src/utils/constant.js:
--------------------------------------------------------------------------------
1 | import { ang2Rad } from "./helper";
2 |
3 | export const cameraProps = {
4 | fov: 60,
5 | // aspect: window.innerWidth / window.innerHeight,
6 | aspect: 16 / 9,
7 | near: 0.1,
8 | far: 2000,
9 | position: {
10 | x: 0,
11 | y: 8,
12 | z: -6,
13 | }
14 | }
15 |
16 | export const orbitControlProps = {
17 | target: {
18 | x: 0,
19 | y: 0,
20 | z: 0,
21 | },
22 | maxPolarAngle: ang2Rad(70),
23 | maxDistance: 50,
24 | minDistance: 5,
25 | }
26 |
27 | export const bloomParams = {
28 | exposure: 1,
29 | bloomStrength: 0.25,
30 | bloomThreshold: 0,
31 | bloomRadius: 0.1
32 | };
33 |
34 | export const hemiLightProps = {
35 | skyColor: 0xcccccc,
36 | groundColor: 0x000000,
37 | intensity: 0.45,
38 | }
39 |
40 | export const spotLightProps = {
41 | color: 0xcccccc,
42 | intensity: 0.6,
43 | position: {
44 | x: -25,
45 | y: 25,
46 | z: 25,
47 | },
48 | castShadow: true,
49 | shadow: {
50 | bias: -0.0001,
51 | mapSize: {
52 | width: 1024 * 4,
53 | height: 1024 * 4,
54 | }
55 | }
56 | }
57 |
58 | export const spotLightProps2 = {
59 | color: 0xcccccc,
60 | intensity: 0.6,
61 | position: {
62 | x: 25,
63 | y: 25,
64 | z: 25,
65 | },
66 | castShadow: true,
67 | shadow: {
68 | bias: -0.0001,
69 | mapSize: {
70 | width: 1024 * 4,
71 | height: 1024 * 4,
72 | }
73 | }
74 | }
75 |
76 | export const pieceMoveSpeed = 10;
77 |
78 | export const aiLevel = 3; // 3: advanced Up to 3;
79 |
80 | export const alphaBet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
81 |
82 | export const tileSize = 1.02;
83 |
84 | export const lightTone = '#b18057';
85 | export const darkTone = '#0a181f';
86 | export const selectTone = '#d78b00';
87 | export const historyTone = '#ff0000';
88 | export const dangerTone = '#d32da7';
89 |
90 | export const boardSize = 8;
91 |
92 | export const modelSize = 0.8;
93 |
94 | export const modelProps = {
95 | 'mountain': {
96 | scale: 1.2,
97 | position: {
98 | x: 16,
99 | y: 0.4,
100 | z: 5,
101 | },
102 | rotate: {
103 | x: 0,
104 | y: 10,
105 | z: 0,
106 | }
107 | },
108 | 'board': {
109 | scale: modelSize + 0.0125,
110 | position: {
111 | x: 0,
112 | y: 0.5,
113 | z: 0,
114 | }
115 | },
116 | 'cell': {
117 | scale: modelSize,
118 | position: {
119 | x: 0,
120 | y: 0.6,
121 | z: 0,
122 | }
123 | }
124 | }
125 |
126 | export const gameModes = {
127 | 'P2E': 0,
128 | 'P2P': 1,
129 | 'practise': 2
130 | }
131 |
132 | export const userTypes = {
133 | 'creator': 0,
134 | 'joiner': 1,
135 | 'observer': 2,
136 | }
137 |
138 | export const resizeUpdateInterval = 500;
139 |
140 | export const heroItems = {
141 | iceWall: 1,
142 | petrify: 2,
143 | jumpyShoe: 3,
144 | springPad: 4,
145 | thunderstorm: 5
146 | };
147 |
148 | export const timeLimit = 30;
--------------------------------------------------------------------------------
/src/utils/helper.js:
--------------------------------------------------------------------------------
1 | import { alphaBet, tileSize } from "./constant";
2 |
3 | export const rad2Ang = (rad) => rad * 180 / Math.PI;
4 |
5 | export const ang2Rad = (ang) => ang * Math.PI / 180;
6 |
7 | export const getRandomVal = (range) => Math.ceil(Math.random() * 100000000) % range;
8 |
9 | export const getMatrixIndexFromFen = (val) => ({
10 | rowIndex: val[1] - 1,
11 | colIndex: alphaBet.indexOf(val[0])
12 | });
13 |
14 | export const getFenFromMatrixIndex = (rowIndex, colIndex) => alphaBet[ colIndex ] + ( rowIndex + 1 );
15 |
16 | export const isSamePoint = (point1, point2) => point1.x === point2.x && point1.y === point2.y && point1.z === point2.z;
17 |
18 | export const getMeshPosition = (rowIndex, colIndex) => ({
19 | x: colIndex * tileSize - tileSize * 3.5,
20 | y: 0.6,
21 | z: -(rowIndex * tileSize - tileSize * 3.5)
22 | })
--------------------------------------------------------------------------------
/src/utils/interact.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { ethers } from 'ethers'
4 | import {chainId} from './address';
5 |
6 | require("dotenv").config()
7 | // const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
8 | // const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
9 | // const web3 = createAlchemyWeb3(alchemyKey)
10 | // const web3 = new Web3('https://ropsten.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161')
11 | // const clanCount = 5
12 |
13 | export const connectWallet = async () => {
14 | if (window.ethereum) {
15 | try {
16 | const chain = await window.ethereum.request({ method: 'eth_chainId' })
17 | console.log("log: ", chain, parseInt(chain, 16), chainId, parseInt(chain, 16) === chainId)
18 | if (parseInt(chain, 16) == chainId) {
19 | const addressArray = await window.ethereum.request({
20 | method: 'eth_requestAccounts',
21 | })
22 | console.log(addressArray)
23 | if (addressArray.length > 0) {
24 | return {
25 | address: addressArray[0],
26 | status: "👆🏽 You can play now.",
27 | }
28 | } else {
29 | return {
30 | address: "",
31 | status: "😥 Connect your wallet account to the site.",
32 | }
33 | }
34 | } else {
35 | window.ethereum.request({
36 | method: 'wallet_switchEthereumChain',
37 | params: [{ chainId:chainId }],
38 | })
39 | return {
40 | address: "",
41 | status: "😥 Connect your wallet account to the site.",
42 | }
43 | }
44 |
45 | } catch (err) {
46 | return {
47 | address: "",
48 | status: "😥 " + err.message,
49 | }
50 | }
51 | } else {
52 | return {
53 | address: "",
54 | status: (
55 |
56 |
57 | {" "}
58 | 🦊{" "}
59 | {/* */}
60 | You must install Metamask, a virtual Ethereum wallet, in your
61 | browser.(https://metamask.io/download.html)
62 | {/* */}
63 |
64 |
65 | ),
66 | }
67 | }
68 | }
69 |
70 | export const getCurrentWalletConnected = async () => {
71 | if (window.ethereum) {
72 | try {
73 | const addressArray = await window.ethereum.request({
74 | method: "eth_accounts",
75 | })
76 | const chain = await window.ethereum.request({
77 | method: "eth_chainId",
78 | })
79 | if (addressArray.length > 0 && chain === chainId) {
80 | return {
81 | address: addressArray[0],
82 | status: "👆🏽 You can play now.",
83 | }
84 | } else {
85 | return {
86 | address: "",
87 | status: "🦊 Connect to Metamask and choose the correct chain using the top right button.",
88 | }
89 | }
90 | } catch (err) {
91 | return {
92 | address: "",
93 | status: "😥 " + err.message,
94 | }
95 | }
96 | } else {
97 | return {
98 | address: "",
99 | status: (
100 |
101 |
102 | {" "}
103 | 🦊{" "}
104 | {/* */}
105 | You must install Metamask, a virtual Ethereum wallet, in your
106 | browser.(https://metamask.io/download.html)
107 | {/* */}
108 |
109 |
110 | ),
111 | }
112 | }
113 | }
114 |
115 | // async function loadContract() {
116 | // return new web3.eth.Contract(contractABI, contractAddress)
117 | // }
118 |
119 | // Contract can be used to write Contract
120 | export const getContractWithSigner = (contractAddress, contractABI) => {
121 | let infuraProvider = new ethers.providers.Web3Provider(window.ethereum)
122 | let signer = infuraProvider.getSigner()
123 |
124 | let contract = new ethers.Contract(
125 | contractAddress,
126 | contractABI,
127 | signer
128 | )
129 |
130 | return contract
131 | }
132 |
133 | // Contract can be used to read Contract
134 | export const getContractWithoutSigner = (contractAddress, contractABI) => {
135 | let infuraProvider = new ethers.providers.Web3Provider(window.ethereum)
136 |
137 | let contract = new ethers.Contract(
138 | contractAddress,
139 | contractABI,
140 | infuraProvider
141 | )
142 |
143 | return contract
144 | }
145 |
146 | export const getContract = (contractAddress, contractABI) => {
147 | let provider = new ethers.providers.Web3Provider(window.ethereum);
148 | let signer = provider.getSigner();
149 |
150 | let contract = new ethers.Contract(contractAddress, contractABI, signer)
151 | return contract
152 | }
--------------------------------------------------------------------------------
/src/utils/llg-contract-abi.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"routerAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"bnbAmount","type":"uint256"}],"name":"AutoBurned","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"bnbAmount","type":"uint256"}],"name":"Burned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountBnb","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nextAvailableClaimDate","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bnbReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensIntoLiqudity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bnbIntoLiquidity","type":"uint256"}],"name":"Swapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"BURN_WALLET","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"activateBuying","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amountUntilSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"antiBlockNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"antiEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"byAddress","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"approveClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoLiquidityWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"byAddress","type":"address"}],"name":"bnbRewardClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"byAddress","type":"address"}],"name":"bnbRewardClaimedAsLLG","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bnbAmount","type":"uint256"}],"name":"buyAndBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"ofAddress","type":"address"}],"name":"calculateBNBReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ofAddress","type":"address"}],"name":"calculateClaimRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculateRewardCycleExtension","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"ofAddress","type":"address"}],"name":"claimRewardAsTokensPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalRewardDampeningPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gradualBurnMagnitude","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gradualBurnTimespan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"holdLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isAutoClaimEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ofAddress","type":"address"},{"internalType":"address","name":"byAddress","type":"address"}],"name":"isClaimApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isExcludedFromFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isExcludedFromHold","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isExcludedFromRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFeeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isInRewardClaimQueue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isIncludedInRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRewardAsTokensEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isRewardReady","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSwapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTokenHoldEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isWhitelistedExternalProcessor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastBurnDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainBnbPoolSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxClaimAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxGasForAutoClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minRewardBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"ofAddress","type":"address"}],"name":"nextAvailableClaimDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pancakeSwapPairAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pancakeSwapRouterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gas","type":"uint256"}],"name":"processRewardClaimQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gas","type":"uint256"}],"name":"processRewardClaimQueueAndRefundGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reimburseAfterLLGClaimFailure","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardClaimQueueIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardClaimQueueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardCyclePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_isEnabled","type":"bool"}],"name":"setAntiBotEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"setAutoClaimEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"liquidityWallet","type":"address"}],"name":"setAutoLiquidityWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"percentage","type":"uint256"}],"name":"setClaimRewardAsTokensPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"devWalletAddress","type":"address"}],"name":"setDevWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"exclude","type":"bool"}],"name":"setExcludeNonHumansFromRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setExcludedFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setExcludedFromHold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"setExcludedFromRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"setFeeEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"liquidityFee","type":"uint8"},{"internalType":"uint8","name":"rewardFee","type":"uint8"},{"internalType":"uint8","name":"marketingFee","type":"uint8"},{"internalType":"uint8","name":"devFee","type":"uint8"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setGlobalRewardDampeningPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"magnitude","type":"uint256"}],"name":"setGradualBurnMagnitude","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"timespan","type":"uint256"}],"name":"setGradualBurnTimespan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"setHoldLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"size","type":"uint256"}],"name":"setMainBnbPoolSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketingWalletAddress","type":"address"}],"name":"setMarketingWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setMaxClaimAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gas","type":"uint256"}],"name":"setMaxGasForAutoClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"setMinRewardBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"routerAddress","type":"address"}],"name":"setPancakeSwapRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setReimburseAfterLLGClaimFailure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"setRewardAsTokensEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"setRewardCycleExtensionThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"period","type":"uint256"}],"name":"setRewardCyclePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setSendWeiGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"setSwapEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"setTokenHoldEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"setTokenSwapThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"setTransactionBuyLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"setTransactionSellLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"isWhitelisted","type":"bool"}],"name":"setWhitelistedExternalProcessor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shouldBurn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"tokenSwapThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAmountOfTokensHeld","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBNBClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBNBClaimedAsLLG","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBNBLiquidityAddedFromFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFeesPooled","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"transactionBuyLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transactionSellLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockNum","type":"uint256"}],"name":"updateBlockNum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
2 |
--------------------------------------------------------------------------------
/src/utils/llg-reward-contract-abi.json:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"_llg","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"bonusWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canGetBonus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"consecutive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_room","type":"uint256"},{"internalType":"address","name":"_playerAddr","type":"address"},{"internalType":"uint256","name":"_funds","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_room","type":"uint256"}],"name":"getDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getLLGBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_playerAddr","type":"address"}],"name":"getNumOfConsecutiveWins","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_playerAddr","type":"address"},{"internalType":"uint256","name":"_room","type":"uint256"},{"internalType":"uint256","name":"_passport","type":"uint256"},{"internalType":"uint256","name":"_numCWins","type":"uint256"}],"name":"giveBonusReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_passport","type":"uint256"}],"name":"issuePassport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"llgContract","outputs":[{"internalType":"contract ILLG","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_room","type":"uint256"},{"internalType":"uint256","name":"_passport","type":"uint256"},{"internalType":"address","name":"_winnerAddr","type":"address"},{"internalType":"bool","name":"isFriendMatch","type":"bool"}],"name":"offerWinningReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_room","type":"uint256"},{"internalType":"uint256","name":"_passport","type":"uint256"},{"internalType":"address","name":"_playerAddr","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"rewarded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"rewardedTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setBonusWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_of","type":"address"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"setConsecutiveCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dateTimeInMillis","type":"uint256"}],"name":"setStartTimeOfDay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_taxPercent","type":"uint256"}],"name":"setTaxPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setTaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTimeOfDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
2 |
--------------------------------------------------------------------------------
/src/utils/packet.js:
--------------------------------------------------------------------------------
1 | export const socketEvents = {
2 | 'CS_CreateRoom': 0xff0001,
3 | 'CS_JoinRoom': 0xff0002,
4 | 'CS_SelectPiece': 0xff0003,
5 | 'CS_PerformMove': 0xff0004,
6 | 'CS_PawnTransform': 0xff0005,
7 | 'CS_UnSelectPiece': 0xff0006,
8 | 'CS_MatchPlayLogin': 0xff0007,
9 | 'CS_ActivateItem': 0xff0008,
10 | 'CS_Ready': 0xff0009,
11 | 'CS_CurrentItem': 0xff0010,
12 | 'CS_SendDrawRequest': 0xff0011,
13 | 'CS_ReplyDrawRequest': 0xff0012,
14 |
15 | 'SC_RoomCreated': 0xff1001,
16 | 'SC_GameStarted': 0xff1002,
17 | 'SC_ChangeTurn': 0xff0103,
18 | 'SC_PlayerLogOut': 0xff1004,
19 | 'SC_ForceExit': 0xff1005,
20 | 'SC_SelectPiece': 0xff1006,
21 | 'SC_PawnTransform': 0xff1007,
22 | 'SC_PerformMove': 0xff1008,
23 | 'SC_UnSelectPiece': 0xff0009,
24 | 'SC_RemainingTime': 0xff0010,
25 | 'SC_ActivateItem': 0xff0011,
26 | 'SC_JoinRoom': 0xff0012,
27 | 'SC_ItemInfo': 0xff0013,
28 | 'SC_SendDrawRequest': 0xff0014,
29 | 'SC_DrawMatch': 0xff0015,
30 | }
--------------------------------------------------------------------------------
/src/views/FriendPlay/index.js:
--------------------------------------------------------------------------------
1 | import { Routes, Route } from "react-router-dom";
2 |
3 | import Play2Earn from "../../components/UI/Play2Earn/Play2Earn";
4 | import CreateGame from "../../components/UI/CreateGame/CreateGame";
5 | import JoinGame from "../../components/UI/JoinGame/JoinGame";
6 | import RoomsScreen from "../../components/UI/RoomsScreen/RoomsScreen";
7 |
8 | export const FriendPlay = () => {
9 | return (
10 |
11 |
12 | } />
13 | } />
14 | } />
15 | } />
16 |
17 |
18 | )
19 | }
20 |
21 | export default FriendPlay;
--------------------------------------------------------------------------------
/src/views/GameScene/CustomOutlinePass.js:
--------------------------------------------------------------------------------
1 | import * as THREE from "three";
2 | import { Pass } from "three/examples/jsm/postprocessing/Pass.js";
3 |
4 | // Follows the structure of
5 | // https://github.com/mrdoob/three.js/blob/master/examples/jsm/postprocessing/OutlinePass.js
6 | class CustomOutlinePass extends Pass {
7 | constructor(resolution, scene, camera, applyOutlineType) {
8 | super();
9 | this.applyOutlineType = applyOutlineType;
10 | this.renderScene = scene;
11 | this.renderCamera = camera;
12 | this.resolution = new THREE.Vector2(resolution.x, resolution.y);
13 | this.fsQuad = new Pass.FullScreenQuad(null);
14 | this.fsQuad.material = this.createOutlinePostProcessMaterial();
15 | // Create a buffer to store the normals of the scene onto
16 | const normalTarget = new THREE.WebGLRenderTarget(
17 | this.resolution.x,
18 | this.resolution.y
19 | );
20 | normalTarget.texture.format = THREE.RGBFormat;
21 | normalTarget.texture.minFilter = THREE.NearestFilter;
22 | normalTarget.texture.magFilter = THREE.NearestFilter;
23 | normalTarget.texture.generateMipmaps = false;
24 | normalTarget.stencilBuffer = false;
25 | // This stores the depth buffer containing
26 | // only objects that will have outlines
27 | normalTarget.depthBuffer = true;
28 | normalTarget.depthTexture = new THREE.DepthTexture();
29 | normalTarget.depthTexture.type = THREE.UnsignedShortType;
30 |
31 | this.normalTarget = normalTarget;
32 | // Create a buffer to store the depth of the scene
33 | // we don't use the default depth buffer because
34 | // this one includes only objects that have the outline applied
35 | const depthTarget = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y );
36 | depthTarget.texture.format = THREE.RGBFormat;
37 | depthTarget.texture.minFilter = THREE.NearestFilter;
38 | depthTarget.texture.magFilter = THREE.NearestFilter;
39 | depthTarget.texture.generateMipmaps = false;
40 | depthTarget.stencilBuffer = false;
41 | depthTarget.depthBuffer = true;
42 | depthTarget.depthTexture = new THREE.DepthTexture();
43 | depthTarget.depthTexture.type = THREE.UnsignedShortType;
44 | this.depthTarget = depthTarget;
45 |
46 | this.normalOverrideMaterial = new THREE.MeshNormalMaterial();
47 | }
48 | dispose() {
49 | this.normalTarget.dispose();
50 | this.fsQuad.dispose();
51 | }
52 | setSize(width, height) {
53 | this.normalTarget.setSize(width, height);
54 | this.resolution.set(width, height);
55 | this.fsQuad.material.uniforms.screenSize.value.set(
56 | this.resolution.x,
57 | this.resolution.y,
58 | 1 / this.resolution.x,
59 | 1 / this.resolution.y
60 | );
61 | }
62 |
63 | // Helper functions for hiding/showing objects based on whether they should have outlines applied
64 | setOutlineObjectsVisibile(bVisible) {
65 | const self = this;
66 | this.renderScene.traverse( function( node ) {
67 | if (node.applyOutline == true && node.applyOutlineType == self.applyOutlineType && node.type == 'Mesh') {
68 |
69 | if (!bVisible) {
70 | node.oldVisibleValue = node.visible;
71 | node.visible = false;
72 | } else {
73 | // Restore original visible value. This way objects
74 | // that were originally hidden stay hidden
75 | if (node.oldVisibleValue != undefined) {
76 | node.visible = node.oldVisibleValue;
77 | delete node.oldVisibleValue;
78 | }
79 | }
80 |
81 |
82 | }
83 | });
84 | }
85 |
86 | setNonOutlineObjectsVisible(bVisible) {
87 | const self = this;
88 | this.renderScene.traverse( function( node ) {
89 | if (node.type == 'Mesh' && (node.applyOutline != true || node.applyOutlineType != self.applyOutlineType)) {
90 |
91 | if (!bVisible) {
92 | node.oldVisibleValue = node.visible;
93 | node.visible = false;
94 | } else {
95 | // Restore original visible value. This way objects
96 | // that were originally hidden stay hidden
97 | if (node.oldVisibleValue != undefined) {
98 | node.visible = node.oldVisibleValue;
99 | delete node.oldVisibleValue;
100 | }
101 | }
102 |
103 |
104 | }
105 | });
106 | }
107 |
108 | /*
109 | This is a modified pipeline from the original outlines effect
110 | to support outlining individual objects.
111 | 1 - Render all objects to get final color buffer, with regular depth buffer
112 | (this is done in index.js)
113 | 2 - Render only non-outlines objects to get `nonOutlinesDepthBuffer`.
114 | (we need this to depth test our outlines so they render behind objects)
115 | 3 - Render all outlines objects to get normal buffer & depth buffer, which are inputs for the outline effect.
116 | This must NOT include objects that won't have outlines applied.
117 | 4 - Render outline effect, using normal and depth buffer that contains only outline objects,
118 | use the `nonOutlinesDepthBuffer` for depth test. And finally combine with the final color buffer.
119 | */
120 |
121 | render(renderer, writeBuffer, readBuffer) {
122 | // Turn off writing to the depth buffer
123 | // because we need to read from it in the subsequent passes.
124 | const depthBufferValue = writeBuffer.depthBuffer;
125 | writeBuffer.depthBuffer = false;
126 | // 1. Re-render the scene to capture all normals in texture.
127 | // Ideally we could capture this in the first render pass along with
128 | // the depth texture.
129 | renderer.setRenderTarget(this.normalTarget);
130 |
131 | const overrideMaterialValue = this.renderScene.overrideMaterial;
132 | this.renderScene.overrideMaterial = this.normalOverrideMaterial;
133 | // Only include objects that have the "applyOutline" property.
134 | // We do this by hiding all other objects temporarily.
135 | this.setNonOutlineObjectsVisible(false);
136 | renderer.render(this.renderScene, this.renderCamera);
137 | this.setNonOutlineObjectsVisible(true);
138 |
139 | this.renderScene.overrideMaterial = overrideMaterialValue;
140 |
141 | // 2. Re-render the scene to capture depth of objects that do NOT have outlines
142 | renderer.setRenderTarget(this.depthTarget);
143 |
144 | this.setOutlineObjectsVisibile(false);
145 | renderer.render(this.renderScene, this.renderCamera);
146 | this.setOutlineObjectsVisibile(true);
147 |
148 | this.fsQuad.material.uniforms["depthBuffer"].value = this.normalTarget.depthTexture;
149 |
150 | this.fsQuad.material.uniforms[
151 | "normalBuffer"
152 | ].value = this.normalTarget.texture;
153 | this.fsQuad.material.uniforms["sceneColorBuffer"].value =
154 | readBuffer.texture;
155 | this.fsQuad.material.uniforms["nonOutlinesDepthBuffer"].value = this.depthTarget.depthTexture;
156 |
157 | // 2. Draw the outlines using the depth texture and normal texture
158 | // 3. Draw the outlines using the depth texture and normal texture
159 | // and combine it with the scene color
160 | if (this.renderToScreen) {
161 | // If this is the last effect, then renderToScreen is true.
162 | // So we should render to the screen by setting target null
163 | // Otherwise, just render into the writeBuffer that the next effect will use as its read buffer.
164 | renderer.setRenderTarget(null);
165 | this.fsQuad.render(renderer);
166 | } else {
167 | renderer.setRenderTarget(writeBuffer);
168 | this.fsQuad.render(renderer);
169 | }
170 | // Reset the depthBuffer value so we continue writing to it in the next render.
171 | writeBuffer.depthBuffer = depthBufferValue;
172 | }
173 | get vertexShader() {
174 | return `
175 | varying vec2 vUv;
176 | void main() {
177 | vUv = uv;
178 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
179 | }
180 | `;
181 | }
182 | get fragmentShader() {
183 | return `
184 | #include
185 | // The above include imports "perspectiveDepthToViewZ"
186 | // and other GLSL functions from ThreeJS we need for reading depth.
187 | uniform sampler2D sceneColorBuffer;
188 | uniform sampler2D depthBuffer;
189 | uniform sampler2D normalBuffer;
190 | uniform sampler2D nonOutlinesDepthBuffer;
191 | uniform float cameraNear;
192 | uniform float cameraFar;
193 | uniform vec4 screenSize;
194 | uniform vec3 outlineColor;
195 | uniform vec4 multiplierParameters;
196 | uniform int debugVisualize;
197 | varying vec2 vUv;
198 | // Helper functions for reading from depth buffer.
199 | float readDepth (sampler2D depthSampler, vec2 coord) {
200 | float fragCoordZ = texture2D(depthSampler, coord).x;
201 | float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
202 | return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
203 | }
204 | float getLinearDepth(vec3 pos) {
205 | return -(viewMatrix * vec4(pos, 1.0)).z;
206 | }
207 | float getLinearScreenDepth(sampler2D map) {
208 | vec2 uv = gl_FragCoord.xy * screenSize.zw;
209 | return readDepth(map,uv);
210 | }
211 | // Helper functions for reading normals and depth of neighboring pixels.
212 | float getPixelDepth(int x, int y) {
213 | // screenSize.zw is pixel size
214 | // vUv is current position
215 | return readDepth(depthBuffer, vUv + screenSize.zw * vec2(x, y));
216 | }
217 | vec3 getPixelNormal(int x, int y) {
218 | return texture2D(normalBuffer, vUv + screenSize.zw * vec2(x, y)).rgb;
219 | }
220 | float saturate(float num) {
221 | return clamp(num, 0.0, 1.0);
222 | }
223 | void main() {
224 | vec4 sceneColor = texture2D(sceneColorBuffer, vUv);
225 | float depth = getPixelDepth(0, 0);
226 | float nonOutlinesDepth = readDepth(nonOutlinesDepthBuffer, vUv + screenSize.zw);
227 | vec3 normal = getPixelNormal(0, 0);
228 | // Get the difference between depth of neighboring pixels and current.
229 | float depthDiff = 0.0;
230 | depthDiff += abs(depth - getPixelDepth(1, 0));
231 | depthDiff += abs(depth - getPixelDepth(-1, 0));
232 | depthDiff += abs(depth - getPixelDepth(0, 1));
233 | depthDiff += abs(depth - getPixelDepth(0, -1));
234 | // Get the difference between normals of neighboring pixels and current
235 | float normalDiff = 0.0;
236 | normalDiff += distance(normal, getPixelNormal(1, 0));
237 | normalDiff += distance(normal, getPixelNormal(0, 1));
238 | normalDiff += distance(normal, getPixelNormal(0, 1));
239 | normalDiff += distance(normal, getPixelNormal(0, -1));
240 | normalDiff += distance(normal, getPixelNormal(1, 1));
241 | normalDiff += distance(normal, getPixelNormal(1, -1));
242 | normalDiff += distance(normal, getPixelNormal(-1, 1));
243 | normalDiff += distance(normal, getPixelNormal(-1, -1));
244 | // Apply multiplier & bias to each
245 | float depthBias = multiplierParameters.x;
246 | float depthMultiplier = multiplierParameters.y;
247 | float normalBias = multiplierParameters.z;
248 | float normalMultiplier = multiplierParameters.w;
249 | depthDiff = depthDiff * depthMultiplier;
250 | depthDiff = saturate(depthDiff);
251 | depthDiff = pow(depthDiff, depthBias);
252 | normalDiff = normalDiff * normalMultiplier;
253 | normalDiff = saturate(normalDiff);
254 | normalDiff = pow(normalDiff, normalBias);
255 | float outline = normalDiff + depthDiff;
256 | // Don't render outlines if they are behind something
257 | // in the original depth buffer
258 | // we find this out by comparing the depth value of current pixel
259 | if ( depth > nonOutlinesDepth && debugVisualize != 4) {
260 | outline = 0.0;
261 | }
262 |
263 | // Combine outline with scene color.
264 | vec4 outlineColor = vec4(outlineColor, 1.0);
265 | gl_FragColor = vec4(mix(sceneColor, outlineColor, outline));
266 | // For debug visualization of the different inputs to this shader.
267 | if (debugVisualize == 1) {
268 | gl_FragColor = sceneColor;
269 | }
270 | if (debugVisualize == 2) {
271 | gl_FragColor = vec4(vec3(depth), 1.0);
272 | }
273 | if (debugVisualize == 5) {
274 | gl_FragColor = vec4(vec3(nonOutlinesDepth), 1.0);
275 | }
276 | if (debugVisualize == 3) {
277 | gl_FragColor = vec4(normal, 1.0);
278 | }
279 | if (debugVisualize == 4) {
280 | gl_FragColor = vec4(vec3(outline * outlineColor), 1.0);
281 | }
282 | }
283 | `;
284 | }
285 | createOutlinePostProcessMaterial() {
286 | return new THREE.ShaderMaterial({
287 | uniforms: {
288 | debugVisualize: { value: 0 },
289 | sceneColorBuffer: {},
290 | depthBuffer: {},
291 | normalBuffer: {},
292 | nonOutlinesDepthBuffer: {},
293 | outlineColor: { value: this.applyOutlineType === 0 ? new THREE.Color(0x00ffff) : new THREE.Color(0xff0000) },
294 | //4 scalar values packed in one uniform: depth multiplier, depth bias, and same for normals.
295 | multiplierParameters: { value:new THREE.Vector4(1, 1, 1, 0.0001) },
296 | cameraNear: { value: this.renderCamera.near },
297 | cameraFar: { value: this.renderCamera.far },
298 | screenSize: {
299 | value: new THREE.Vector4(
300 | this.resolution.x,
301 | this.resolution.y,
302 | 1 / this.resolution.x,
303 | 1 / this.resolution.y
304 | ),
305 | },
306 | },
307 | vertexShader: this.vertexShader,
308 | fragmentShader: this.fragmentShader,
309 | });
310 | }
311 | }
312 | export { CustomOutlinePass };
--------------------------------------------------------------------------------
/src/views/GameScene/GameScene.scss:
--------------------------------------------------------------------------------
1 | .GameScene {
2 | position: relative;
3 | display: grid;
4 | align-items: center;
5 | text-align: center;
6 | width: 100vw;
7 | height: 100vh;
8 | background-image: url("../../assets/img/modal_back.png");
9 | background-repeat: no-repeat;
10 | background-size: 100% 100%;
11 | .game-container {
12 | position: relative;
13 | margin: auto;
14 | .game-canvas {
15 | width: 100%;
16 | height: 100%;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/views/GameScene/index.js:
--------------------------------------------------------------------------------
1 | import { useLocation } from "react-router-dom";
2 | import { Game } from 'js-chess-engine'
3 |
4 | import Scene from "./GameScene";
5 | import { gameModes } from "../../utils/constant";
6 | import { getRandomVal } from "../../utils/helper";
7 |
8 | import store from "../../store/store";
9 |
10 | const game = new Game();
11 |
12 | console.error(game);
13 |
14 | export const GameScene = () => {
15 | const location = useLocation();
16 |
17 | const color = [ 'white', 'black' ];
18 | const side = location.state.mode === gameModes['P2E'] ? color[getRandomVal(2)] : null;
19 |
20 | const socket = store( state => state.socket );
21 |
22 | return (
23 |
24 |
25 |
26 | )
27 | }
28 |
29 | export default GameScene;
--------------------------------------------------------------------------------
/src/views/MatchPlay/index.js:
--------------------------------------------------------------------------------
1 | import MatchPlayLogin from "../../components/UI/MatchPlayLogin/MatchPlayLogin";
2 |
3 | export const MatchPlay = () => {
4 | return (
5 |
6 | )
7 | }
8 |
9 | export default MatchPlay;
--------------------------------------------------------------------------------