remove flow types - it was inconsistently used and therefore pointless

devel
HF 1 year ago
parent 79b4f55a04
commit d4ef69c2ac

1
.gitignore vendored

@ -4,6 +4,7 @@ output.webm
utils/ocean-tiles/ocean
utils/osm-tiles/osm
i18n/*.mo
test.js
logs
*.log

@ -2,8 +2,6 @@ const pkg = require('./package.json');
module.exports = function (api) {
const plugins = [
'@babel/plugin-transform-flow-strip-types',
'@babel/plugin-proposal-throw-expressions',
// react-optimize
'@babel/transform-react-constant-elements',
'@babel/transform-react-inline-elements',

1958
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -3,8 +3,7 @@
"version": "1.0.0",
"private": true,
"engines": {
"node": ">=10.16.0",
"npm": ">=6.13.4"
"node": ">=14"
},
"description": "Unlimited planet canvas for placing pixels",
"main": "server.js",
@ -66,6 +65,7 @@
"three-trackballcontrols": "^0.9.0",
"ttag": "^1.7.24",
"url-search-params-polyfill": "^8.1.1",
"whoiser": "^1.13.1",
"winston": "^3.8.1",
"winston-daily-rotate-file": "^4.5.5",
"ws": "^8.4.0"
@ -75,8 +75,6 @@
"@babel/core": "^7.18.6",
"@babel/eslint-parser": "^7.16.5",
"@babel/node": "^7.18.6",
"@babel/plugin-proposal-throw-expressions": "^7.18.6",
"@babel/plugin-transform-flow-strip-types": "^7.18.6",
"@babel/plugin-transform-react-constant-elements": "^7.18.6",
"@babel/plugin-transform-react-inline-elements": "^7.18.6",
"@babel/preset-env": "^7.18.6",

@ -6,7 +6,6 @@
* also:
* echo never > /sys/kernel/mm/transparent_hugepage/enabled
*
* @flow
*/
/* eslint-disable no-console */
@ -86,7 +85,7 @@ backupRedis.on('error', () => {
});
function runCmd(cmd: string) {
function runCmd(cmd) {
const startTime = Date.now();
console.log(`Executing ${cmd}`);
const cmdproc = spawn(cmd);

@ -1,6 +1,5 @@
/*
*
* @flow
*/
import React, { useState, useEffect, useCallback } from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/*
* Change Mail Form
* @flow
*/
import React, { useState } from 'react';

@ -1,6 +1,5 @@
/*
* Change Name Form
* @flow
*/
import React, { useState } from 'react';

@ -1,6 +1,5 @@
/*
* Change Password Form
* @flow
*/
import React, { useState } from 'react';

@ -1,7 +1,3 @@
/*
*
* @flow
*/
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';
@ -11,7 +10,7 @@ import copy from '../utils/clipboard';
import { notify } from '../store/actions';
function renderCoordinates(cell): string {
function renderCoordinates(cell) {
return `(${cell.join(', ')})`;
}

@ -1,6 +1,5 @@
/*
* Rankings Tabs
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/*
* Change Password Form
* @flow
*/
import React, { useState } from 'react';

@ -1,6 +1,5 @@
/*
* LogIn Form
* @flow
*/
import React, {
useState, useCallback, useRef,

@ -5,7 +5,6 @@
* Available languages under window.langSel
* [['hz', 'am'], ['de', 'de'], ...]
* [languageCode, countryCode (for flag)]
* @flow
*/
import React, { useState, useEffect } from 'react';
import { t } from 'ttag';

@ -1,5 +1,4 @@
/*
* @flow
*/
import React from 'react';
import { useDispatch } from 'react-redux';

@ -1,6 +1,5 @@
/*
* LogIn Form
* @flow
*/
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';

@ -1,7 +1,6 @@
/*
* Menu with Buttons on the top left
*
* @flow
*/
import React, { useState, useEffect } from 'react';

@ -1,6 +1,5 @@
/*
*
* @flow
* Menu for WASD keys for mobile users
*/

@ -2,7 +2,6 @@
*
* https://stackoverflow.com/questions/35623656/how-can-i-display-a-modal-dialog-in-redux-that-performs-asynchronous-actions/35641680#35641680
*
* @flow
*/
import React, { useState, useEffect } from 'react';

@ -1,6 +1,5 @@
/*
* Modtools
* @flow
*/
import React, { useState, useEffect } from 'react';

@ -1,8 +1,3 @@
/**
*
* @flow
*/
import React, { useState, useEffect } from 'react';
import { useSelector } from 'react-redux';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React, { useState, useEffect } from 'react';

@ -1,6 +1,5 @@
/*
* Rankings Tabs
* @flow
*/
/* eslint-disable max-len */

@ -1,6 +1,5 @@
/*
* Change Mail Form
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/*
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/*
* Rankings Tabs
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/*
* Menu to change user credentials
* @flow
*/
import React, { useState, useCallback } from 'react';

@ -1,6 +1,5 @@
/*
* Messages on top of UserArea
* @flow
*/
import React, { useState } from 'react';
import { useSelector } from 'react-redux';

@ -1,6 +1,5 @@
/*
* draw window
* @flow
*/
import React, {

@ -1,6 +1,5 @@
/*
* draw windows
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React, {
@ -104,7 +103,7 @@ const ChatButton = () => {
>⦿</div>
)}
<MdForum />
</div>: null
</div>
);
};

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,7 +1,6 @@
/*
* espand menu / show other menu buttons
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,7 +1,6 @@
/**
*
* Button to open/close palette
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/*
*
* @flow
*/
import React, { useRef, useCallback } from 'react';

@ -1,7 +1,6 @@
/*
* Drop Down menu for Chat Channel selection
*
* @flow
*/
import React, {

@ -1,6 +1,5 @@
/*
*
* @flow
*/
import React, { useRef } from 'react';

@ -1,7 +1,3 @@
/*
* @flow
*/
/* eslint-disable max-len */
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React, { useCallback } from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React, {

@ -1,6 +1,5 @@
/*
* Form for requesting password-reset mail
* @flow
*/
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';

@ -1,6 +1,5 @@
/*
* SignUp Form to register new user by mail
* @flow
*/
import React, { useState } from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React from 'react';

@ -1,6 +1,5 @@
/**
*
* @flow
*/
import React, { Suspense } from 'react';

@ -4,7 +4,6 @@
* keycodes:
* https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
*
* @flow
*/
import {
@ -31,7 +30,7 @@ import {
} from '../core/utils';
class PixelPlainterControls {
constructor(renderer, viewport: HTMLCanvasElement, curStore) {
constructor(renderer, viewport, curStore) {
this.store = curStore;
this.renderer = renderer;
this.viewport = viewport;
@ -101,7 +100,7 @@ class PixelPlainterControls {
}, delta * 1000);
}
onMouseDown(event: MouseEvent) {
onMouseDown(event) {
event.preventDefault();
document.activeElement.blur();
@ -129,7 +128,7 @@ class PixelPlainterControls {
}, 250);
}
onMouseUp(event: MouseEvent) {
onMouseUp(event) {
event.preventDefault();
const { store } = this;
@ -161,7 +160,7 @@ class PixelPlainterControls {
store.dispatch(onViewFinishChange());
}
static getTouchCenter(event: TouchEvent) {
static getTouchCenter(event) {
switch (event.touches.length) {
case 1: {
const { pageX, pageY } = event.touches[0];
@ -251,7 +250,7 @@ class PixelPlainterControls {
);
}
static getMultiTouchDistance(event: TouchEvent) {
static getMultiTouchDistance(event) {
if (event.touches.length < 2) {
return 1;
}
@ -262,7 +261,7 @@ class PixelPlainterControls {
);
}
onTouchStart(event: TouchEvent) {
onTouchStart(event) {
event.preventDefault();
event.stopPropagation();
document.activeElement.blur();
@ -292,7 +291,7 @@ class PixelPlainterControls {
}
}
onTouchEnd(event: TouchEvent) {
onTouchEnd(event) {
event.preventDefault();
event.stopPropagation();
@ -328,7 +327,7 @@ class PixelPlainterControls {
this.clearTabTimeout();
}
onTouchMove(event: TouchEvent) {
onTouchMove(event) {
event.preventDefault();
event.stopPropagation();
@ -384,7 +383,7 @@ class PixelPlainterControls {
}
}
onWheel(event: MouseEvent) {
onWheel(event) {
event.preventDefault();
document.activeElement.blur();
@ -405,7 +404,7 @@ class PixelPlainterControls {
this.scheduleOnViewFinishChange();
}
onMouseMove(event: MouseEvent) {
onMouseMove(event) {
event.preventDefault();
const { clientX, clientY } = event;
@ -503,7 +502,7 @@ class PixelPlainterControls {
}
}
onAuxClick(event: MouseEvent) {
onAuxClick(event) {
const { which, clientX, clientY } = event;
// middle mouse button
if (which !== 2) {
@ -519,7 +518,7 @@ class PixelPlainterControls {
);
}
onKeyUp(event: KeyboardEvent) {
onKeyUp(event) {
switch (event.key) {
case 'Shift':
case 'CapsLock':
@ -529,7 +528,7 @@ class PixelPlainterControls {
}
}
onKeyDown(event: KeyboardEvent) {
onKeyDown(event) {
// ignore key presses if modal is open or chat is used
if (event.target.nodeName === 'INPUT'
|| event.target.nodeName === 'TEXTAREA'

@ -2,7 +2,6 @@
* Buffer for chatMessages for the server
* it just buffers the msot recent 200 messages for each channel
*
* @flow
*/
import Sequelize from 'sequelize';
import logger from './logger';

@ -492,8 +492,8 @@ export class ChatProvider {
message,
channelId,
id,
country: string = 'xx',
sendapi: boolean = true,
country = 'xx',
sendapi = true,
) {
if (message.length > 250) {
return;

@ -1,74 +0,0 @@
/* @flow */
/**
* Created by http://code.stephenmorley.org/javascript/queues/
*/
class Queue<T> {
array: Array<T>;
offset: number;
constructor() {
this.array = [];
this.offset = 0;
}
/**
*
* @returns {number} the length of the queue.
*/
getLength(): number {
return this.array.length - this.offset;
}
/**
* Returns true if the queue is empty, and false otherwise.
* @returns {boolean}
*/
isEmpty(): boolean {
return this.array.length === 0;
}
/**
* Enqueues the specified item. The parameter is:
* @param item the item to enqueue
*/
enqueue(item: T) {
this.array.push(item);
}
/**
* Dequeues an item and returns it. If the queue is empty, the value
* 'undefined' is returned.
*/
dequeue(): ?T {
// if the queue is empty, return immediately
if (this.isEmpty()) return null;
// store the item at the front of the queue
const item = this.array[this.offset];
// increment the first and remove the free space if necessary
this.offset += 1;
if (this.offset * 2 >= this.array.length) {
this.array = this.array.slice(this.offset);
this.offset = 0;
}
// return the dequeued item
return item;
}
/**
* Returns the item at the front of the queue (without dequeuing it). If the
* queue is empty then undefined is returned.
* @returns {*}
*/
peek(): ?T {
if (this.isEmpty()) return null;
return this.array[this.offset];
}
}
export default Queue;

@ -2,7 +2,6 @@
* This is an even that happens all 2h,
* if the users complete, they will get rewarded by half the cooldown sitewide
*
* @flow
*/
import logger from './logger';
@ -66,17 +65,17 @@ function drawCross(centerCell, clr, style, radius) {
class RpgEvent {
eventState: number;
eventTimestamp: number;
eventCenter: Array;
eventCenterC: Array;
eventArea: Array;
eventState; // number
eventTimestamp; // number
eventCenter; // Array
eventCenterC; // Array
eventArea; // Array
// 0 if waiting
// 1 if won
// 2 if lost
success: boolean;
void: Object;
chatTimeout: number;
success; // boolean
void; // Object
chatTimeout; // number
constructor() {
this.eventState = -1;

@ -1,4 +1,3 @@
/* @flow */
// general config that is also available from client code can be found in
// src/core/constants.js
import path from 'path';

@ -1,5 +1,4 @@
/**
* @flow
*/
// canvas size (width and height) MUST be 256 * 4^n to be able to stick

@ -1,6 +1,5 @@
/*
*
* @flow
*/
function appendNumberText(number) {

@ -1,7 +1,3 @@
/**
* @flow
* */
import fetch from '../utils/proxiedFetch';
import redis from '../data/redis/client';
@ -18,7 +14,7 @@ import { USE_PROXYCHECK } from './config';
* @return true if proxy, false if not
*/
// eslint-disable-next-line no-unused-vars
async function getIPIntel(ip: string): Promise<boolean> {
async function getIPIntel(ip) {
// eslint-disable-next-line max-len
const email = `${Math.random().toString(36).substring(8)}-${Math.random().toString(36).substring(4)}@gmail.com`;
// eslint-disable-next-line max-len
@ -33,8 +29,6 @@ async function getIPIntel(ip: string): Promise<boolean> {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
},
});
// TODO log response code
logger.debug('PROXYCHECK getipintel? %s', ip);
if (!response.ok) {
const text = await response.text();
throw new Error(`PROXYCHECK getipintel not ok ${response.status}/${text}`);
@ -52,7 +46,7 @@ async function getIPIntel(ip: string): Promise<boolean> {
* @param ip IP to check
* @return true if proxy, false if not
*/
async function getProxyCheck(ip: string): Promise<boolean> {
async function getProxyCheck(ip) {
const url = `http://proxycheck.io/v2/${ip}?risk=1&vpn=1&asn=1`;
logger.info('PROXYCHECK fetching proxycheck %s', url);
const response = await fetch(url, {
@ -70,37 +64,12 @@ async function getProxyCheck(ip: string): Promise<boolean> {
return data.status === 'ok' && data[ip].proxy === 'yes';
}
/*
* check shroomey if IP is proxy
* NOTE: shroomey can not check IPv6
* User random proxies for request, just to be sure
* @param ip IP to check
* @return true if proxy, false if not
*/
async function getShroomey(ip: string): Promise<boolean> {
logger.info('PROXYCHECK fetching shroomey %s', ip);
// eslint-disable-next-line max-len
const response = await fetch(`http://www.shroomery.org/ythan/proxycheck.php?ip=${ip}`, {
headers: {
Accept: '*/*',
'Accept-Language': 'es-ES,es;q=0.8,en;q=0.6',
Referer: 'http://www.shroomery.org/',
// eslint-disable-next-line max-len
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
},
});
if (!response.ok) throw new Error('shroomery.org not ok');
const body = await response.text();
logger.info('PROXYCHECK fetch shroomey is proxy? %s %s', ip, body);
return body === 'Y';
}
/*
* check MYSQL Blacklist table
* @param ip IP to check
* @return true if blacklisted
*/
async function isBlacklisted(ip: string): Promise<boolean> {
async function isBlacklisted(ip) {
const count = await Blacklist
.count({
where: {
@ -115,7 +84,7 @@ async function isBlacklisted(ip: string): Promise<boolean> {
* @param ip IP to check
* @return true if whitelisted
*/
async function isWhitelisted(ip: string): Promise<boolean> {
async function isWhitelisted(ip) {
const count = await Whitelist
.count({
where: {
@ -128,7 +97,7 @@ async function isWhitelisted(ip: string): Promise<boolean> {
/*
* dummy function to include if you don't want any proxycheck
*/
async function dummy(): Promise<boolean> {
async function dummy() {
return false;
}
@ -167,13 +136,8 @@ async function withCache(f, ip) {
const key = `isprox:${ipKey}`;
const cache = await redis.get(key);
if (cache) {
logger.debug('PROXYCHECK fetch isproxy from cache %s %s %s',
key,
cache,
typeof cache);
return cache === 'y';
}
logger.debug('PROXYCHECK fetch isproxy not from cache %s', key);
// else make asynchronous ipcheck and assume no proxy in the meantime
// use lock to just check three at a time
@ -201,17 +165,13 @@ async function withCache(f, ip) {
return false;
}
export function cheapDetector(ip: string): Promise<boolean> {
export function cheapDetector(ip) {
if (USE_PROXYCHECK) {
return withCache(getProxyCheck, ip);
}
return withCache(dummy, ip);
}
export function strongDetector(ip: string): Promise<boolean> {
return withCache(getShroomey, ip);
}
export function blacklistDetector(ip: string): Promise<boolean> {
export function blacklistDetector(ip) {
return withCache(dummy, ip);
}

@ -2,7 +2,6 @@
*
* http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
*
* @flow
*/
import { createLogger, format, transports } from 'winston';

@ -3,7 +3,6 @@
* Userdata that gets sent to the client on
* various api endpoints.
*
* @flow
*/
// eslint-disable-next-line import/no-unresolved
import { getLocalicedCanvases } from '../canvasesDesc';

@ -1,7 +1,6 @@
/**
* https://scotch.io/tutorials/easy-node-authentication-linking-all-accounts-together#toc-linking-accounts-together
*
* @flow
*/
import passport from 'passport';

@ -1,6 +1,5 @@
/*
* timers and cron for account related actions
* @flow
*/
import Sequelize from 'sequelize';
@ -13,7 +12,7 @@ import { MINUTE } from './constants';
import { DailyCron } from '../utils/cron';
class Ranks {
ranks: Array;
ranks; // Array
constructor() {
this.updateRanking = this.updateRanking.bind(this);

@ -1,7 +1,6 @@
/*
* Rolls back an area of the canvas to a specific date
*
* @flow
*/
// Tile creation is allowed to be slow
@ -21,12 +20,12 @@ import { BACKUP_DIR } from './config';
import canvases from './canvases.json';
export default async function rollbackToDate(
canvasId: number,
x: number,
y: number,
width: number,
height: number,
date: string,
canvasId, // number
x, // number
y, // number
width, // number
height, // number
date, // string
) {
if (!BACKUP_DIR) {
return 0;

@ -1,6 +1,5 @@
/*
* Provide translation serverside
* @flow
*/
import { TTag } from 'ttag';
import cookie from 'cookie';

@ -173,7 +173,7 @@ export function getPixelFromChunkOffset(
j,
offset,
canvasSize,
is3d: boolean = false,
is3d = false,
) {
const tileSize = (is3d) ? THREE_TILE_SIZE : TILE_SIZE;
const cx = offset % tileSize;
@ -225,7 +225,7 @@ export function worldToScreen(
export function durationToString(
ms,
smallest: boolean = false,
smallest = false,
) {
const seconds = Math.ceil(ms / 1000);
let timestring;
@ -297,7 +297,7 @@ export function colorFromText(str) {
/*
* sets a color into bright or dark mode
*/
export function setBrightness(hex, dark: boolean = false) {
export function setBrightness(hex, dark = false) {
hex = hex.replace(/^\s*#|\s*$/g, '');
if (hex.length === 3) {

@ -11,7 +11,6 @@
* Reference:
* https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox.txt
*
* @flow
*/
/*

@ -4,7 +4,6 @@
* loged in or not.
* If user is not logged in, id = null
*
* @flow
* */
import { QueryTypes, Utils } from 'sequelize';
@ -49,21 +48,21 @@ export const regUserQueryInclude = [{
}];
class User {
id: string;
ip: string;
wait: ?number;
regUser: Object;
channels: Object;
blocked: Array;
id; // string
ip; // string
wait; // ?number
regUser; // Object
channels; // Object
blocked; // Array
/*
* 0: nothing
* 1: Admin
* 2: Mod
*/
userlvl: number;
userlvl; // number
constructor() {
// if id = null -> unregistered
// if id = 0 -> unregistered
this.id = 0;
this.regUser = null;
this.ip = '127.0.0.1';
@ -185,7 +184,7 @@ class User {
return true;
}
async getWait(canvasId: number): Promise<?number> {
async getWait(canvasId) {
let ttl = await redis.pTTL(`cd:${canvasId}:ip:${this.ipSub}`);
if (this.id) {
const ttlid = await redis.pTTL(
@ -199,7 +198,7 @@ class User {
return wait;
}
async incrementPixelcount(amount: number = 1): Promise<boolean> {
async incrementPixelcount(amount = 1) {
const { id } = this;
if (!id) return false;
try {
@ -213,7 +212,7 @@ class User {
return true;
}
async getTotalPixels(): Promise<number> {
async getTotalPixels() {
const { id } = this;
if (!id) return 0;
if (this.userlvl === 1) return 100000;
@ -244,7 +243,7 @@ class User {
}
}
async updateLogInTimestamp(): Promise<boolean> {
async updateLogInTimestamp() {
if (!this.regUser) return false;
try {
await this.regUser.update({
@ -256,7 +255,7 @@ class User {
return true;
}
getUserData(): Object {
getUserData() {
const {
id,
userlvl,

@ -43,12 +43,12 @@ const Channel = sequelize.define('Channel', {
updatedAt: false,
getterMethods: {
lastTs(): number {
lastTs() {
return new Date(this.lastMessage).valueOf();
},
},
setterMethods: {
lastTs(ts: number) {
lastTs(ts) {
this.setDataValue('lastMessage', new Date(ts).toISOString());
},
},

@ -110,36 +110,36 @@ const RegUser = sequelize.define('User', {
updatedAt: false,
getterMethods: {
mailVerified(): boolean {
mailVerified() {
return this.verified & 0x01;
},
blockDm(): boolean {
blockDm() {
return this.blocks & 0x01;
},
isMod(): boolean {
isMod() {
return this.roles & 0x01;
},
},
setterMethods: {
mailVerified(num: boolean) {
mailVerified(num) {
const val = (num) ? (this.verified | 0x01) : (this.verified & ~0x01);
this.setDataValue('verified', val);
},
blockDm(num: boolean) {
blockDm(num) {
const val = (num) ? (this.blocks | 0x01) : (this.blocks & ~0x01);
this.setDataValue('blocks', val);
},