Giter Site home page Giter Site logo

ltfschoen / flappytips Goto Github PK

View Code? Open in Web Editor NEW
11.0 2.0 2.0 3.56 MB

FlappyTips 2. Polkadot ecosystem game

License: GNU General Public License v3.0

HTML 1.86% CSS 1.67% JavaScript 73.63% Rust 16.51% Procfile 0.01% DIGITAL Command Language 3.64% Shell 2.67%
p5js-game web3 polkadot-js react heroku kusama-network polkadot-network treasury ink-language smart-contracts

flappytips's Issues

Mobile user can still connect and win and beat Desktop users. Twitter message doesn't reflect game result

Mobile user can still win and beat Desktop users. It shows that they lost in Twitter message if they share the result even though they won (they could easily edit it) and shows they won in the UI and wanted to shared on twitter. Since it's not a native game it requires them to sign in to Twitter to share it.

We weren't going to let Mobile users win since they can't sign in with QR code, so users that aren't even establishing that they have a Substrate address loaded can play

Need to change logic from chainAccountResult === chainAccount ... to chainAccountResult === chainAccount && chainAccount !== 'DEMO-MOBILE' ...

Prevent users from submitting a fake game result

Users could slow their CPU speed down to make it easier to win.
Possibly record the timestamp when the user starts playing and when they finish, and how many obstacles they cleared, and compare that with the actual time between the start and end blocks they played.
Send block hash of the to the server and verify its valid

could restrict each account to play once per day (approx x blocks) but we don't want to force people to have an account with an identity or require a payment to play

only allow a win if winning score was higher than y, otherwise a lose (prevent spam)

Refresh multiple times if does not immediate detect extension sometimes

This may be associated with browser cache.

After playing a game if you choose to "Play Again" it refreshes the page but sometimes it doesn't detect the Polkadot.js Extension immediately and it's necessary to right click the browser refresh button and choose "Empty Cache and Hard Reload" a few times before it recognises the extension and bypasses that modal that says "FlappyTips 2 on Desktop: Install and enable Polkadot.js Extension Desktop users"

Can't play in two incognito windows because one of them doesn't allow you to choose "Empty Cache and Hard Reload"

But can play using IP address in one window i.e. https://139.144.96.196 and with domain in the other https://clawbird.com

Prevent user from sharing awesomeness when balance insufficient to pay for submission

At the moment a user can choose an account thats injected from Polkadot.js Extension (Desktop) or enter a Mnemonic Seed (Mobile), but that account could be an inactive account or a dust account and the extrinsic could fail. So it would be better UX to detect and warn the user that they have insufficient balance before they even try to submit

Linode deployment websockets solution

  • Replace usage of https://flappytips.herokuapp.com with the actual production endpoint like https://139.144.96.196 (since we're using Linode instead.
  • Linode production deployment was modified in production and got rid of WSS errors with multiplayer. But local code in development still produces this error when use yarn run dev.
WebSocket connection to 'ws://localhost:4000/ws' failed: 
WebSocketClient @ WebSocketClient.js:16
initSocket @ socket.js:24
(anonymous) @ socket.js:48
websocket.js:40 WebSocket connection to 'ws://localhost:5000/socket.io/?EIO=4&transport=websocket' failed: 
  • Linode process.env was not previously working with WSS variable. Had to define it as let WSS = true in each file instead. Some changes were made to CORS too. Figure out why that allowed it to overcome this error websocket.js:40 WebSocket connection to 'ws://localhost:5000/socket.io/?EIO=4&transport=websocket' failed: in production or on Heroku the error was WebSocket connection to 'wss://flappytips.herokuapp.com:5000/socket.io/?EIO=4&transport=websocket' failed: WebSocket is closed before the connection is established., such that if this happens in-game then it doesn't record the game ended block, and sits "Waiting for results...". Incorporate these hotfixes into the code, like changes in snippets below:
const corsWhitelist = [
  'https://139.144.96.196:443',
  'http://139.144.96.196:80',
  'https://139.144.96.196:4000',
  'https://139.144.96.196:5000',
  'http://139.144.96.196:4000',
  'http://139.144.96.196:5000',

if (process.env.NODE_ENV === 'production' && process.env.WSS) {
  proxy_url = `https:///139.144.96.196:${proxy_port}`;
} else if (process.env.NODE_ENV === 'production' && process.env.WSS !== true) {
  proxy_url = `http:///139.144.96.196:${proxy_port}`;
} else if (process.env.NODE_ENV !== 'production') {
  proxy_url = 'http:///139.144.96.196:5000';

let socketEndpoint = process.env.NODE_ENV === 'production'
  ? (
    process.env.WSS === true
    ? `wss://http://139.144.96.196:${PORT}`
    : `ws://http://139.144.96.196:${PORT}`

It was not necessary to do these things:

https://stackoverflow.com/a/31481025/3208553
https://socket.io/docs/v4/using-multiple-nodes/
https://devcenter.heroku.com/articles/session-affinity
8aaaadc

Prevent multiple blocks overtaking each other making gameplay impossible

Fix issue where the block obstacle after the current block obstacle might go much faster and overtake, making it impossible to get through... make min space between obstacles somehow. This sometimes impacts one player but not another since game speed varies between players which is a consistency issue.

Request all tips to a governance account in the smart contract where tips claimed

with a fee split between going to the oracle, some into a pot to fund transactions to the smart contract to record each winner automatically and the rest going to the player.

custom chain governance proposal so community can vote as the oracle about who in game result was the winner in case of disputes, then the oracle account address needs to report the outcome to Zeitgeist within 24 hours

Refer to this code that shows an approach to splitting fees https://github.com/SkymanOne/vote-pray-love/blob/d44e042306a323ad64c9d9ebc5f42d3d84acdd17/pallets/slashing-voting/src/lib.rs

German mentioned:

websocket.js:44 WebSocket connection to 'wss://clawbird.com:5000/socket.io/?EIO=4&transport=websocket' failed: One or more reserved bits are on: reserved1 = 1, reserved2 = 0, reserved3 = 0

Relates to this repository with latest code in PR #85

The error in production when i run yarn && yarn start is:

WebSocket connection to 'wss://clawbird.com:5000/socket.io/?EIO=4&transport=websocket' failed: One or more reserved bits are on: reserved1 = 1, reserved2 = 0, reserved3 = 0

It says the error is occurring on this line of the engine.io-client dependency https://github.com/socketio/engine.io-client/blob/main/lib/transports/websocket.ts#L78

It occurs in the file /src/sketches/sketch.js where I try to instantiate and connect to a Socket.IO endpoint

An old post mentioned they resolved a similar issue by upgrading Nginx, so I tried updating from Nginx 1.18 to 1.23.3 so nginx -V returned nginx version: nginx/1.23.3 but it still returned the same error

So I enabled Websockets debugging mentioned here https://socket.io/docs/v4/logging-and-debugging/ and then viewed the errors in the server logs:

[HPM] Upgrading to WebSocket
[HPM] Error occurred while proxying request clawbird.com:5000/socket.io/?EIO=4&transport=websocket to undefined [ECONNRESET] (https://nodejs.org/api/errors.html#errors_common_system_errors)
[HPM] WebSocket error: Error: read ECONNRESET
    at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20) {
  errno: -104,
  code: 'ECONNRESET',
  syscall: 'read'
}
[HPM] Upgrading to WebSocket
[HPM] Error occurred while proxying request clawbird.com:5000/socket.io/?EIO=4&transport=websocket to undefined [ECONNRESET] (https://nodejs.org/api/errors.html#errors_common_system_errors)
[HPM] WebSocket error: Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at new NodeError (node:internal/errors:399:5)
    at _write (node:internal/streams/writable:322:11)
    at Writable.write (node:internal/streams/writable:337:10)
    at Sender.sendFrame (/var/www/.yarn/__virtual__/ws-virtual-b72ae8e9d2/0/cache/ws-npm-8.11.0-ab72116a01-316b33aba3.zip/node_modules/ws/lib/sender.js:469:20)
    at Sender.send (/var/www/.yarn/__virtual__/ws-virtual-b72ae8e9d2/0/cache/ws-npm-8.11.0-ab72116a01-316b33aba3.zip/node_modules/ws/lib/sender.js:359:12)
    at WebSocket.send (/var/www/.yarn/__virtual__/ws-virtual-b72ae8e9d2/0/cache/ws-npm-8.11.0-ab72116a01-316b33aba3.zip/node_modules/ws/lib/websocket.js:468:18)
    at send (/var/www/.yarn/cache/engine.io-npm-6.4.0-1d74810449-bff0127303.zip/node_modules/engine.io/build/transports/websocket.js:84:29)
    at Object.encodePacket (/var/www/.yarn/cache/engine.io-parser-npm-5.0.6-6021cc2c82-e92255b546.zip/node_modules/engine.io-parser/build/cjs/encodePacket.js:10:12)
    at WebSocket.send (/var/www/.yarn/cache/engine.io-npm-6.4.0-1d74810449-bff0127303.zip/node_modules/engine.io/build/transports/websocket.js:95:29)
    at Socket.flush (/var/www/.yarn/cache/engine.io-npm-6.4.0-1d74810449-bff0127303.zip/node_modules/engine.io/build/socket.js:417:28) {
  code: 'ERR_STREAM_WRITE_AFTER_END'

Maybe Nginx 1.18 and 1.23.3 aren't compatible with NPM package socket.io-client 4.6.0 ?

I'm already using the latest Yarn 3 and Node.js 19.6.0

So I updated package.json to use latest 4.6.1

    "socket.io": "^4.6.1",
    "socket.io-client": "^4.6.1",

but that still returned the same error when i restarted the website.

It returns the following to curl request:

curl "https://clawbird.com:5000/socket.io/?EIO=4&transport=websocket"

{"code":3,"message":"Bad request"}

The error in development when after I change WSS=false in constants/index.js and in src/constants.js, and run yarn && yarn run dev using HTTP/WS i get error:

WebSocket connection to 'ws://localhost:5000/socket.io/?EIO=4&transport=websocket' failed:

screenshot:

Screen Shot 2023-02-21 at 2 56 16 pm

and the server logs are:

[0] [HPM] Upgrading to WebSocket
[0] :socket sending packet "open" ({"sid":"JsX-unkjfAg0-P_0AAqB","upgrades":[],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000})
[0] 2023-02-21T05:11:13.833Z engine:socket flushing buffer to transport
[0] 2023-02-21T05:11:13.833Z engine:ws writing "0{"sid":"JsX-unkjfAg0-P_0AAqB","upgrades":[],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000}"
[0] 2023-02-21T05:11:13.833Z engine:transport setting request
[0] 2023-02-21T05:11:13.833Z socket.io:server incoming connection with id JsX-unkjfAg0-P_0AAqB
[0] 2023-02-21T05:11:13.837Z engine applying middleware n°1
[0] 2023-02-21T05:11:13.837Z engine writing headers: {"Access-Control-Allow-Origin":"http://localhost:5000","Vary":"Origin"}
[0] 2023-02-21T05:11:13.838Z engine handshaking client "Yd2CGv_Vai5thT_pAAqC"
[0] 2023-02-21T05:11:13.839Z engine:transport readyState updated from undefined to open (websocket)
[0] 2023-02-21T05:11:13.839Z engine:socket readyState updated from undefined to opening
[0] 2023-02-21T05:11:13.839Z engine:socket readyState updated from opening to open
[0] 2023-02-21T05:11:13.839Z engine:socket sending packet "open" ({"sid":"Yd2CGv_Vai5thT_pAAqC","upgrades":[],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000})
[0] 2023-02-21T05:11:13.839Z engine:socket flushing buffer to transport
[0] 2023-02-21T05:11:13.839Z engine:ws writing "0{"sid":"Yd2CGv_Vai5thT_pAAqC","upgrades":[],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000}"
[0] 2023-02-21T05:11:13.839Z engine:transport setting request
[0] 2023-02-21T05:11:13.839Z socket.io:server incoming connection with id Yd2CGv_Vai5thT_pAAqC
[0] 2023-02-21T05:11:13.841Z engine applying middleware n°1
[0] 2023-02-21T05:11:13.841Z engine writing headers: {"Access-Control-Allow-Origin":"http://localhost:5000","Vary":"Origin"}
[0] 2023-02-21T05:11:13.841Z engine handshaking client "zzvpEfEzbVvHqk_RAAqD"
[0] 2023-02-21T05:11:13.841Z engine:transport readyState updated from undefined to open (websocket)
[0] 2023-02-21T05:11:13.841Z engine:socket readyState updated from undefined to opening
[0] 2023-02-21T05:11:13.841Z engine:socket readyState updated from opening to open
[0] 2023-02-21T05:11:13.841Z engine:socket sending packet "open" ({"sid":"zzvpEfEzbVvHqk_RAAqD","upgrades":[],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000})
[0] 2023-02-21T05:11:13.841Z engine:socket flushing buffer to transport
[0] 2023-02-21T05:11:13.841Z engine:ws writing "0{"sid":"zzvpEfEzbVvHqk_RAAqD","upgrades":[],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000}"
[0] 2023-02-21T05:11:13.841Z engine:transport setting request
[0] 2023-02-21T05:11:13.841Z socket.io:server incoming connection with id zzvpEfEzbVvHqk_RAAqD
[0] 2023-02-21T05:11:13.843Z engine applying middleware n°1
[0] 2023-02-21T05:11:13.843Z engine writing headers: {"Access-Control-Allow-Origin":"http://localhost:5000","Vary":"Origin"}
[0] 2023-02-21T05:11:13.843Z engine handshaking client "jMT4b1SUEl2Wb2kmAAqE"
[0] 2023-02-21T05:11:13.843Z engine:transport readyState updated from undefined to open (websocket)
[0] 2023-02-21T05:11:13.843Z engine:socket readyState updated from undefined to opening
[0] 2023-02-21T05:11:13.843Z engine:socket readyState updated from opening to open
[0] 2023-02-21T05:11:13.847Z engine:socket sending packet "open" ({"sid":"jMT4b1SUEl2Wb2kmAAqE","upgrades":[],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000})
[0] 2023-02-21T05:11:13.847Z engine:socket flushing buffer to transport
[0] 2023-02-21T05:11:13.847Z engine:ws writing "0{"sid":"jMT4b1SUEl2Wb2kmAAqE","upgrades":[],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000}"
[0] 2023-02-21T05:11:13.847Z engine:transport setting request
[0] 2023-02-21T05:11:13.847Z socket.io:server incoming connection with id jMT4b1SUEl2Wb2kmAAqE
[0] 2023-02-21T05:11:13.850Z engine:transport readyState updated from open to closed (websocket)
[0] 2023-02-21T05:11:13.850Z engine:socket readyState updated from open to closed
[0] 2023-02-21T05:11:13.850Z socket.io:client client close with reason transport close
[0] 2023-02-21T05:11:13.850Z socket.io-parser encoding packet {"type":2,"data":["gameDataPlayers",{}],"nsp":"/"}
[0] 2023-02-21T05:11:13.850Z socket.io-parser encoded {"type":2,"data":["gameDataPlayers",{}],"nsp":"/"} as 2["gameDataPlayers",{}]
[0] [HPM] WebSocket error: Error [ERR_STREAM_WRITE_AFTER_END]: write after end
[0]     at new NodeError (node:internal/errors:387:5)
[0]     at _write (node:internal/streams/writable:321:11)
[0]     at Socket.Writable.write (node:internal/streams/writable:336:10)
[0]     at ClientRequest.<anonymous> (~/code/github/ltfschoen/flappytips2/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js:143:14)
[0]     at ClientRequest.emit (node:events:513:28)
[0]     at Socket.socketOnData (node:_http_client:574:11)
[0]     at Socket.emit (node:events:513:28)
[0]     at addChunk (node:internal/streams/readable:315:12)
[0]     at readableAddChunk (node:internal/streams/readable:289:9)
[0]     at Socket.Readable.push (node:internal/streams/readable:228:10) {
[0]   code: 'ERR_STREAM_WRITE_AFTER_END'
[0] }
[0] [HPM] WebSocket error: Error [ERR_STREAM_WRITE_AFTER_END]: write after end
[0]     at new NodeError (node:internal/errors:387:5)
[0]     at _write (node:internal/streams/writable:321:11)
[0]     at Socket.Writable.write (node:internal/streams/writable:336:10)
[0]     at ClientRequest.<anonymous> (~/code/github/ltfschoen/flappytips2/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js:143:14)
[0]     at ClientRequest.emit (node:events:513:28)
[0]     at Socket.socketOnData (node:_http_client:574:11)
[0]     at Socket.emit (node:events:513:28)
[0]     at addChunk (node:internal/streams/readable:315:12)
[0]     at readableAddChunk (node:internal/streams/readable:289:9)
[0]     at Socket.Readable.push (node:internal/streams/readable:228:10) {
[0]   code: 'ERR_STREAM_WRITE_AFTER_END'
[0] }
[0] [HPM] WebSocket error: Error [ERR_STREAM_WRITE_AFTER_END]: write after end
[0]     at new NodeError (node:internal/errors:387:5)
[0]     at _write (node:internal/streams/writable:321:11)
[0]     at Socket.Writable.write (node:internal/streams/writable:336:10)
[0]     at ClientRequest.<anonymous> (~/code/github/ltfschoen/flappytips2/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js:143:14)
[0]     at ClientRequest.emit (node:events:513:28)
[0]     at Socket.socketOnData (node:_http_client:574:11)
[0]     at Socket.emit (node:events:513:28)
[0]     at addChunk (node:internal/streams/readable:315:12)
[0]     at readableAddChunk (node:internal/streams/readable:289:9)
[0]     at Socket.Readable.push (node:internal/streams/readable:228:10) {
[0]   code: 'ERR_STREAM_WRITE_AFTER_END'
[0] }
[0] [HPM] WebSocket error: Error [ERR_STREAM_WRITE_AFTER_END]: write after end
[0]     at new NodeError (node:internal/errors:387:5)
[0]     at _write (node:internal/streams/writable:321:11)
[0]     at Socket.Writable.write (node:internal/streams/writable:336:10)
[0]     at ClientRequest.<anonymous> (~/code/github/ltfschoen/flappytips2/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js:143:14)
[0]     at ClientRequest.emit (node:events:513:28)
[0]     at Socket.socketOnData (node:_http_client:574:11)
[0]     at Socket.emit (node:events:513:28)
[0]     at addChunk (node:internal/streams/readable:315:12)
[0]     at readableAddChunk (node:internal/streams/readable:289:9)
[0]     at Socket.Readable.push (node:internal/streams/readable:228:10) {
[0]   code: 'ERR_STREAM_WRITE_AFTER_END'
[0] }
[0] [HPM] WebSocket error: Error [ERR_STREAM_WRITE_AFTER_END]: write after end
[0]     at new NodeError (node:internal/errors:387:5)
[0]     at _write (node:internal/streams/writable:321:11)
[0]     at Socket.Writable.write (node:internal/streams/writable:336:10)
[0]     at ClientRequest.<anonymous> (~/code/github/ltfschoen/flappytips2/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js:143:14)
[0]     at ClientRequest.emit (node:events:513:28)
[0]     at Socket.socketOnData (node:_http_client:574:11)
[0]     at Socket.emit (node:events:513:28)
[0]     at addChunk (node:internal/streams/readable:315:12)
[0]     at readableAddChunk (node:internal/streams/readable:289:9)
[0]     at Socket.Readable.push (node:internal/streams/readable:228:10) {
[0]   code: 'ERR_STREAM_WRITE_AFTER_END'
[0] }
[0] [HPM] WebSocket error: Error [ERR_STREAM_WRITE_AFTER_END]: write after end
[0]     at new NodeError (node:internal/errors:387:5)
[0]     at _write (node:internal/streams/writable:321:11)
    at Socket.Writable.write ([HPM] Client disconnected

...

But if I remove the following code:

// https://github.com/chimurai/http-proxy-middleware/blob/master/examples/websocket/index.js
httpServer.on('upgrade', wsProxy.upgrade); // optional: upgrade externally
...
// https://www.npmjs.com/package/http-proxy-middleware#external-websocket-upgrade
const wsProxy = createProxyMiddleware({
 	  target: proxy_url,
 	  changeOrigin: true,
 	  ws: true,
 	  logger: console,
});
...
app.use('/socket.io/', wsProxy);

Then it works in development successfully without any errors and i can player multiplayer properly.

It seems like when it's working successfully, it uses both:

  • ws://localhost:4000/ws
  • ws://localhost:5000/socket.io/?EIO=4&transport=websocket

So if I removed those same lines from production,

and in the backend i changed the host to the IP address of the production server to https://${HOST_IP_ADDRESS}:5000

const httpServer = `https://clawbird.com:5000`
 const io = require("socket.io")(httpServer, {
   transports: ["websocket"],
   path: "/socket.io/",
   cors: {
     origin: proxy_url,
     credentials: true,
   }
 });

and in the frontend set the socket endpoint to https://clawbird.com:5000

const socketEndpoint = ;
const socket = io('https://clawbird.com:5000', {
  transports: ["websocket"],
  addTrailingSlash: true,
  path: "/socket.io/",
  withCredentials: true,
});

and lastly changed the following:

PORT = 5000;
httpServer.listen(
  PORT,
  process.env.NODE_ENV === 'production' ? HOST_IP_ADDRESS : '0.0.0.0',
);

then it worked again in production too

CSP Twitter image

Unsure how to update CSP when it displays the syndication.twitter.com/i/jot/embeds?l=%7B%22widget_origin%22%3A%22https%3A%2F%2Fclawbird.com%2F%22%2C%22widget_frame%22%3Afalse%2C%22language%22%3A%22en%22%2C%22message%22%3A%.......... net::ERR_BLOCKED_BY_CLIENT error in console when it opens the "Share & Request Tip (on-chain)!" modal, since i think that embed might be dynamic

This isn't important because the image still loads and it all still works

twitter relevant parts of the CSP are already

 Content-Security-Policy "default-src 'self' 'unsafe-eval'; upgrade-insecure-requests; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval' platform.twitter.com syndication.twitter.com; script-src-elem 'self' https://platform.twitter.com/widgets.js https://platform.twitter.com/js/button.e7f9415a2e000feaab02c86dd5802747.js; img-src 'self' data: https://syndication.twitter.com; frame-src 'self' https://platform.twitter.com/";

Inactive browser tab vs Active browser tab both lose

If you start one player in a Brave browser window tab, then start another player in a new incognito window of Brave, then if the first player changes to a different tab in the browser whilst the other player plays and clears a block, then when you open the second players window only then does their block obstacle appear, and if they don't clear any blocks you'd expect the second player to win since they cleared a block, but the result is that both lose for some reason...

Maybe need to check if the current browser tab isn't active at all during the game then the player automatically loses or game is invalidated... and prevent this behaviour repeating somehow

HTTP to HTTPS redirection only works on latest Firefox by not the latest Chrome or Brave

https://stackoverflow.com/questions/21106998/nginx-redirect-http-to-https-and-non-www-to-ww/75499730#75499730

I couldn't figure out why HTTP http://example.com wouldn't redirect to HTTPS https://example.com. i had configured it the following way like others have and according to https://nginx.org/en/docs/http/configuring_https_servers.html, even after restarting the server with nginx -s reload && sudo systemctl restart nginx

/etc/nginx/sites-available/example.com

server {
    listen 80;
    server_name www.example.com example.com;
    return 301 https://$server_name$request_uri;
}

server {
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 1m;

    listen                  443 ssl http2 default_server;
    listen                  [::]:443 ssl http2 default_server;
    server_name             www.example.com example.com;
    root                    /var/www/build;
    index                   index.html;
    location / {
                            try_files $uri /index.html =404;
    }
}

But even though i'm using the latest browsers, the redirection from HTTP to HTTPS only works with the latest in incognito window:

  • Firefox: 110.0 (64-bit) (both on Desktop and Mobile)

But not with the latest in incognito window even after clear cache and hard reload:

  • Brave: Version 1.48.164 Chromium: 110.0.5481.100 (Official Build) (x86_64)
  • Chrome: Version 110.0.5481.100 (Official Build) (x86_64)

With Brave and Chrome it just loads the default HTTP page "Welcome to nginx!" from /var/www/html/
index.nginx-debian.html

net::ERR_CERT_COMMON_NAME_INVALID

Relates to #77 , only affects mobile devices, desktop works ok

Sometimes the mobile device can't connect to multiple desktop players at all though... when I inspected the browser console for the mobile device it gave error WebSocket connection to 'wss://139.144.96.196:5000/socket.io/?EIO=4&transport=websocket' failed: Error in connection establishment: net::ERR_CERT_COMMON_NAME_INVALID even though the certificate had common name clawbird.com (worked with Let's Encrypt, but then didn't work after i swapped to Sectigo CA, but then when i swapped back to Let's Encrypt it didn't work there anymore either on mobile

Multiplayer game winner will lose if all other players leave the game or press Play Again before they finish

If you play two player on mobile, and if player 1 hits the first obstacle but the other player 2 doesn't hit the first obstacle, then player 1 result will be "waiting for other results", and on player 2's screen it will still show player 1 in the opponent list shown in blue, but if player 1 leaves the game (closes the browser tab, or even presses "Play Again") then they won't appear on the opponent list for player 2 anymore, and if that happens before player 2 hits a subsequent obstacle, then player 2 will lose because the game isn't correctly keeping the context of all the players that actually started anymore.

so need a fix where even if player 1 leaves the game before player 2 also hits a subsequent obstacle, player 2 will win...
and we need to communicate what's going on to the players

but also don't want a situation where someone with multiple browser devices and multiple browser tabs open tries to play them all at the same time... possible but hard.... and since some openings are at the bottom of the screen they might clear some obstacles not even pressing anything and possibly win... and don't want them spamming games

so we need the following changes:

  • first obstacle must prevent players clearing it if they don't press anything (i.e. the gap can't extend all the way to the bottom)
  • only allow a winning result if at least two players joined the game at a starting block (that's already the case) and if at least two players clear the a high number like the x-th block (proof of actually playing lol), to make it harder to win, and to have less asking for tips, and to make it harder to predict the result on prediction markets
    • note: we don't penalise them for not clearing the first block because players also need to learn to play, and we don't want to discourage them by throttling how often they can play just because they're learning keep hitting the first block (not spam)
  • add a "Practice" button instead of just "Play" so players can just learn to clear blocks, and allow them to play immediately single player (also for those who are addicted to the game and too impatient to wait for other players to play a game)
  • penalise players that click "Play" (instead of practicing by clicking "Practice" enough) but that don't clear at least the first block by making them wait say 30 blocks until they can play again (how long measured in blocks is the average game length? if it's 10 then they miss about 3 games). this is to prevent players spamming to win. this could just be stored on the backend, but could also be stored in a smart contract as a form of game player credibility..

cargo-contract error[E0432]: unresolved import `contract_build::metadata::METADATA_FILE

When I ran cargo install cargo-contract --version 2.0.0-rc.1 on macOS it gave the following error:

    Compiling wasm-opt v0.111.0
    error[E0432]: unresolved import `contract_build::metadata::METADATA_FILE`
      --> /Users/luke/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-contract-2.0.0-rc.1/src/cmd/extrinsics/mod.rs:85:5
      |
    85 | use contract_build::metadata::METADATA_FILE;
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `METADATA_FILE` in `metadata`

    For more information about this error, try `rustc --explain E0432`.
    The following warnings were emitted during compilation:

    warning: Git command failed with status: exit status: 128
    warning: Could not find `.git/HEAD` searching from `/Users/luke/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-contract-2.0.0-rc.1` upwards!

    error: could not compile `cargo-contract` due to previous error
    error: failed to compile `cargo-contract v2.0.0-rc.1`, intermediate artifacts can be found at `/var/folders/69/n6p09m3d6t5d7tw5kn9f3kkm0000gq/T/cargo-installytfbPN`

Application error

If you go to flappytips.herokuapp.com it gives an 'Application error'

Update to React 18

react-dom.development.js:86 Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot

Replace old syntax with new, like useEffect, etc

Retrieve wallet info returns 403

Previously I able to use the 'hs-client' library to retrieve Wallet Info with

  // Get Wallet Info
  const wallet = walletClient.wallet('primary');
  const result = await wallet.getInfo();
  console.log('Wallet Info: ', result);

And the output was:

Wallet Info:  {
  network: 'main',
  wid: 0,
  id: 'primary',
  watchOnly: false,
  accountDepth: 1,
  token: '...',
  tokenDepth: 0,
  master: { encrypted: false },
  balance: {
    account: -1,
    tx: 0,
    coin: 0,
    unconfirmed: 0,
    confirmed: 0,
    lockedUnconfirmed: 0,
    lockedConfirmed: 0
  }
}

But now when i run the same query, the response is:

Error: Status code: 403.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.