eslint auto-fix

This commit is contained in:
HF 2020-01-04 07:00:47 +01:00
parent aa8c666ceb
commit 520dc1655e
79 changed files with 354 additions and 286 deletions

View File

@ -671,4 +671,3 @@ export function switchCanvas(canvasId: number): PromiseAction {
dispatch(onViewFinishChange()); dispatch(onViewFinishChange());
}; };
} }

View File

@ -52,10 +52,7 @@ export type Action =
| { type: 'SHOW_MODAL', modalType: string, modalProps: obj } | { type: 'SHOW_MODAL', modalType: string, modalProps: obj }
| { type: 'HIDE_MODAL' } | { type: 'HIDE_MODAL' }
| { type: 'RELOAD_URL' } | { type: 'RELOAD_URL' }
| { type: 'ON_VIEW_FINISH_CHANGE' } | { type: 'ON_VIEW_FINISH_CHANGE' };
;
export type PromiseAction = Promise<Action>; export type PromiseAction = Promise<Action>;
export type ThunkAction = (dispatch: Dispatch, getState: GetState) => any; export type ThunkAction = (dispatch: Dispatch, getState: GetState) => any;
export type Dispatch = (action: Action | ThunkAction | PromiseAction | Array<Action>) => any; export type Dispatch = (action: Action | ThunkAction | PromiseAction | Array<Action>) => any;

View File

@ -132,8 +132,9 @@ function initViewport() {
let lastScale = initialState.canvas.scale; let lastScale = initialState.canvas.scale;
hammertime.on( hammertime.on(
'panstart pinchstart pan pinch panend pinchend', 'panstart pinchstart pan pinch panend pinchend',
({ type, deltaX, deltaY, scale }, ({
) => { type, deltaX, deltaY, scale,
}) => {
viewport.style.cursor = 'move'; // like google maps viewport.style.cursor = 'move'; // like google maps
const { scale: viewportScale } = store.getState().canvas; const { scale: viewportScale } = store.getState().canvas;
@ -192,7 +193,9 @@ document.addEventListener('DOMContentLoaded', () => {
const renderer = new Renderer(); const renderer = new Renderer();
renderer.setViewport(viewport); renderer.setViewport(viewport);
ProtocolClient.on('pixelUpdate', ({ i, j, offset, color }) => { ProtocolClient.on('pixelUpdate', ({
i, j, offset, color,
}) => {
store.dispatch(receivePixelUpdate(i, j, offset, color)); store.dispatch(receivePixelUpdate(i, j, offset, color));
// render updated pixel // render updated pixel
renderer.renderPixel(i, j, offset, color); renderer.renderPixel(i, j, offset, color);

View File

@ -44,7 +44,6 @@ const data = {
description: 'admin access on pixelplanet', description: 'admin access on pixelplanet',
body: <Admin />, body: <Admin />,
}; };
const adminHtml = const adminHtml = `<!doctype html>${ReactDOM.renderToStaticMarkup(<Html {...data} />)}`;
`<!doctype html>${ReactDOM.renderToStaticMarkup(<Html {...data} />)}`;
export default adminHtml; export default adminHtml;

View File

@ -4,7 +4,9 @@
*/ */
import React from 'react'; import React from 'react';
import { validateName, validateEMail, validatePassword, parseAPIresponse } from '../utils/validation'; import {
validateName, validateEMail, validatePassword, parseAPIresponse,
} from '../utils/validation';
function validate(email, password) { function validate(email, password) {
const errors = []; const errors = [];
@ -87,19 +89,19 @@ class ChangeMail extends React.Component {
return ( return (
<div className="inarea"> <div className="inarea">
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
{errors.map(error => ( {errors.map((error) => (
<p key={error} className="errormessage">Error: {error}</p> <p key={error} className="errormessage">Error: {error}</p>
))} ))}
<input <input
value={this.state.password} value={this.state.password}
onChange={evt => this.setState({ password: evt.target.value })} onChange={(evt) => this.setState({ password: evt.target.value })}
type="password" type="password"
placeholder="Password" placeholder="Password"
/> />
<br /> <br />
<input <input
value={this.state.email} value={this.state.email}
onChange={evt => this.setState({ email: evt.target.value })} onChange={(evt) => this.setState({ email: evt.target.value })}
type="text" type="text"
placeholder="New Mail" placeholder="New Mail"
/> />

View File

@ -74,12 +74,12 @@ class ChangeName extends React.Component {
return ( return (
<div className="inarea"> <div className="inarea">
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
{errors.map(error => ( {errors.map((error) => (
<p key={error} className="errormessage">Error: {error}</p> <p key={error} className="errormessage">Error: {error}</p>
))} ))}
<input <input
value={this.state.name} value={this.state.name}
onChange={evt => this.setState({ name: evt.target.value })} onChange={(evt) => this.setState({ name: evt.target.value })}
type="text" type="text"
placeholder="New Username" placeholder="New Username"
/> />

View File

@ -60,7 +60,9 @@ class ChangePassword extends React.Component {
async handleSubmit(e) { async handleSubmit(e) {
e.preventDefault(); e.preventDefault();
const { password, new_password, confirm_password, submitting } = this.state; const {
password, new_password, confirm_password, submitting,
} = this.state;
if (submitting) return; if (submitting) return;
const errors = validate(this.props.mailreg, password, new_password, confirm_password); const errors = validate(this.props.mailreg, password, new_password, confirm_password);
@ -95,28 +97,29 @@ class ChangePassword extends React.Component {
return ( return (
<div className="inarea"> <div className="inarea">
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
{errors.map(error => ( {errors.map((error) => (
<p key={error} className="errormessage">Error: {error}</p> <p key={error} className="errormessage">Error: {error}</p>
))} ))}
{(this.props.mailreg) && {(this.props.mailreg)
&& (
<input <input
value={this.state.password} value={this.state.password}
onChange={evt => this.setState({ password: evt.target.value })} onChange={(evt) => this.setState({ password: evt.target.value })}
type="password" type="password"
placeholder="Old Password" placeholder="Old Password"
/> />
} )}
<br /> <br />
<input <input
value={this.state.new_password} value={this.state.new_password}
onChange={evt => this.setState({ new_password: evt.target.value })} onChange={(evt) => this.setState({ new_password: evt.target.value })}
type="password" type="password"
placeholder="New Password" placeholder="New Password"
/> />
<br /> <br />
<input <input
value={this.state.confirm_password} value={this.state.confirm_password}
onChange={evt => this.setState({ confirm_password: evt.target.value })} onChange={(evt) => this.setState({ confirm_password: evt.target.value })}
type="password" type="password"
placeholder="Confirm New Password" placeholder="Confirm New Password"
/> />

View File

@ -26,20 +26,21 @@ const Chat = ({ chatMessages }) => {
<div style={{ height: '100%' }}> <div style={{ height: '100%' }}>
<ul className="chatarea" ref={listRef}> <ul className="chatarea" ref={listRef}>
{ {
chatMessages.map(message => ( chatMessages.map((message) => (
<p className="chatmsg"> <p className="chatmsg">
{(message[0] == 'info') ? {(message[0] == 'info')
<span style={{ color: '#cc0000' }}>{message[1]}</span> : ? <span style={{ color: '#cc0000' }}>{message[1]}</span>
<div> : (
<span className="chatname" style={{ color: colorFromText(message[0]) }}>{`${message[0]}: `}</span> <div>
{ <span className="chatname" style={{ color: colorFromText(message[0]) }}>{`${message[0]}: `}</span>
{
splitCoordsInString(message[1]).map((text, i) => { splitCoordsInString(message[1]).map((text, i) => {
if (i % 2 == 0) { return (<span className="msg">{text}</span>); } if (i % 2 == 0) { return (<span className="msg">{text}</span>); }
return (<a href={`./${text}`}>{text}</a>); return (<a href={`./${text}`}>{text}</a>);
}) })
} }
</div> </div>
} )}
</p> </p>
)) ))
} }

View File

@ -13,10 +13,12 @@ import Chat from './Chat';
const ChatBox = ({ chatOpen }) => ( const ChatBox = ({ chatOpen }) => (
<div> <div>
{(chatOpen) ? {(chatOpen)
<div className="chatbox"> ? (
<Chat /> <div className="chatbox">
</div> : null} <Chat />
</div>
) : null}
</div> </div>
); );

View File

@ -42,7 +42,7 @@ class ChatInput extends React.Component {
<input <input
style={{ maxWidth: '80%', width: '240px' }} style={{ maxWidth: '80%', width: '240px' }}
value={this.state.message} value={this.state.message}
onChange={evt => this.setState({ message: evt.target.value })} onChange={(evt) => this.setState({ message: evt.target.value })}
type="text" type="text"
placeholder="Chat here" placeholder="Chat here"
/> />

View File

@ -19,14 +19,15 @@ const DailyRankings = ({ totalDailyRanking }) => (
<th>Total Pixels</th> <th>Total Pixels</th>
</tr> </tr>
{ {
totalDailyRanking.map(rank => ( totalDailyRanking.map((rank) => (
<tr> <tr>
<td>{rank.dailyRanking}</td> <td>{rank.dailyRanking}</td>
<td>{rank.name}</td> <td>{rank.name}</td>
<td>{rank.dailyTotalPixels}</td> <td>{rank.dailyTotalPixels}</td>
<td>{rank.ranking}</td> <td>{rank.ranking}</td>
<td>{rank.totalPixels}</td> <td>{rank.totalPixels}</td>
</tr>)) </tr>
))
} }
</table> </table>
</div> </div>

View File

@ -72,12 +72,12 @@ class DeleteAccount extends React.Component {
return ( return (
<div className="inarea" style={{ backgroundColor: '#ff6666' }}> <div className="inarea" style={{ backgroundColor: '#ff6666' }}>
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
{errors.map(error => ( {errors.map((error) => (
<p key={error} className="errormessage">Error: {error}</p> <p key={error} className="errormessage">Error: {error}</p>
))} ))}
<input <input
value={this.state.password} value={this.state.password}
onChange={evt => this.setState({ password: evt.target.value })} onChange={(evt) => this.setState({ password: evt.target.value })}
type="password" type="password"
placeholder="Password" placeholder="Password"
/> />

View File

@ -24,7 +24,7 @@ function download(view) {
const [x, y] = view.map(Math.round); const [x, y] = view.map(Math.round);
const filename = `pixelplanet-${x}-${y}.png`; const filename = `pixelplanet-${x}-${y}.png`;
$viewport.toBlob(blob => fileDownload(blob, filename)); $viewport.toBlob((blob) => fileDownload(blob, filename));
} }

View File

@ -19,7 +19,9 @@ function globe(canvasId, canvasIdent, canvasSize, view) {
} }
const GlobeButton = ({ canvasId, canvasIdent, canvasSize, view }) => ( const GlobeButton = ({
canvasId, canvasIdent, canvasSize, view,
}) => (
<div id="globebutton" className="actionbuttons" onClick={() => globe(canvasId, canvasIdent, canvasSize, view)}> <div id="globebutton" className="actionbuttons" onClick={() => globe(canvasId, canvasIdent, canvasSize, view)}>
<Md3DRotation /> <Md3DRotation />
</div> </div>
@ -27,8 +29,12 @@ const GlobeButton = ({ canvasId, canvasIdent, canvasSize, view }) => (
// TODO optimize // TODO optimize
function mapStateToProps(state: State) { function mapStateToProps(state: State) {
const { canvasId, canvasIdent, canvasSize, view } = state.canvas; const {
return { canvasId, canvasIdent, canvasSize, view }; canvasId, canvasIdent, canvasSize, view,
} = state.canvas;
return {
canvasId, canvasIdent, canvasSize, view,
};
} }
export default connect(mapStateToProps)(GlobeButton); export default connect(mapStateToProps)(GlobeButton);

View File

@ -31,7 +31,9 @@ class Html extends React.Component {
}; };
render() { render() {
const { title, description, styles, scripts, body, code, useRecaptcha } = this.props; const {
title, description, styles, scripts, body, code, useRecaptcha,
} = this.props;
return ( return (
<html className="no-js" lang="en"> <html className="no-js" lang="en">
<head> <head>
@ -45,14 +47,14 @@ class Html extends React.Component {
content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"
/> />
<link rel="apple-touch-icon" href="apple-touch-icon.png" /> <link rel="apple-touch-icon" href="apple-touch-icon.png" />
{styles.map(style => {styles.map((style) => (
(<style <style
key={style.id} key={style.id}
id={style.id} id={style.id}
// eslint-disable-next-line react/no-danger // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style.cssText }} dangerouslySetInnerHTML={{ __html: style.cssText }}
/>), />
)} ))}
{RECAPTCHA_SITEKEY && useRecaptcha && <script dangerouslySetInnerHTML={{ __html: `window.sitekey="${RECAPTCHA_SITEKEY}"` }} />} {RECAPTCHA_SITEKEY && useRecaptcha && <script dangerouslySetInnerHTML={{ __html: `window.sitekey="${RECAPTCHA_SITEKEY}"` }} />}
{RECAPTCHA_SITEKEY && useRecaptcha && <script src="https://www.google.com/recaptcha/api.js" async defer />} {RECAPTCHA_SITEKEY && useRecaptcha && <script src="https://www.google.com/recaptcha/api.js" async defer />}
</head> </head>
@ -64,18 +66,20 @@ class Html extends React.Component {
// eslint-disable-next-line react/no-danger // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: code }} dangerouslySetInnerHTML={{ __html: code }}
/> />
{scripts.map(script => <script key={script} src={script} />)} {scripts.map((script) => <script key={script} src={script} />)}
{analytics.google.trackingId && {analytics.google.trackingId
&& (
<script <script
// eslint-disable-next-line react/no-danger // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: dangerouslySetInnerHTML={{
'window.ga=function(){ga.q.push(arguments)};ga.q=[];ga.l=+new Date;' + __html:
`ga('create','${analytics.google.trackingId}','auto');ga('send','pageview')` }} 'window.ga=function(){ga.q.push(arguments)};ga.q=[];ga.l=+new Date;'
+ `ga('create','${analytics.google.trackingId}','auto');ga('send','pageview')`,
}}
/> />
} )}
{analytics.google.trackingId && {analytics.google.trackingId
<script src="https://www.google-analytics.com/analytics.js" async defer /> && <script src="https://www.google-analytics.com/analytics.js" async defer />}
}
</body> </body>
</html> </html>
); );

View File

@ -3,14 +3,16 @@
* @flow * @flow
*/ */
import React from 'react'; import React from 'react';
import { validateEMail, validateName, validatePassword, parseAPIresponse } from '../utils/validation'; import {
validateEMail, validateName, validatePassword, parseAPIresponse,
} from '../utils/validation';
function validate(nameoremail, password) { function validate(nameoremail, password) {
const errors = []; const errors = [];
const mailerror = (nameoremail.indexOf('@') !== -1) ? const mailerror = (nameoremail.indexOf('@') !== -1)
validateEMail(nameoremail) : ? validateEMail(nameoremail)
validateName(nameoremail); : validateName(nameoremail);
if (mailerror) errors.push(mailerror); if (mailerror) errors.push(mailerror);
const passworderror = validatePassword(password); const passworderror = validatePassword(password);
if (passworderror) errors.push(passworderror); if (passworderror) errors.push(passworderror);
@ -80,20 +82,20 @@ class LogInForm extends React.Component {
const { errors } = this.state; const { errors } = this.state;
return ( return (
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
{errors.map(error => ( {errors.map((error) => (
<p key={error}>Error: {error}</p> <p key={error}>Error: {error}</p>
))} ))}
<input <input
style={inputStyles} style={inputStyles}
value={this.state.nameoremail} value={this.state.nameoremail}
onChange={evt => this.setState({ nameoremail: evt.target.value })} onChange={(evt) => this.setState({ nameoremail: evt.target.value })}
type="text" type="text"
placeholder="Name or Email" placeholder="Name or Email"
/> />
<input <input
style={inputStyles} style={inputStyles}
value={this.state.password} value={this.state.password}
onChange={evt => this.setState({ password: evt.target.value })} onChange={(evt) => this.setState({ password: evt.target.value })}
type="password" type="password"
placeholder="Password" placeholder="Password"
/> />

View File

@ -14,8 +14,8 @@ import { ASSET_SERVER } from '../core/config';
const data = { const data = {
title: 'PixelPlanet.fun', title: 'PixelPlanet.fun',
description: 'Place color pixels on an map styled canvas ' + description: 'Place color pixels on an map styled canvas '
'with other players online', + 'with other players online',
// styles: [ // styles: [
// { id: 'css', cssText: baseCss }, // { id: 'css', cssText: baseCss },
// ], // ],
@ -35,8 +35,7 @@ const data = {
*/ */
function generateMainPage(countryCoords: Cell): string { function generateMainPage(countryCoords: Cell): string {
const [x, y] = countryCoords; const [x, y] = countryCoords;
const code = const code = `window.coordx=${x};window.coordy=${y};window.assetserver="${ASSET_SERVER}";`;
`window.coordx=${x};window.coordy=${y};window.assetserver="${ASSET_SERVER}";`;
const htmldata = { ...data, code }; const htmldata = { ...data, code };
const html = ReactDOM.renderToStaticMarkup(<Html {...htmldata} />); const html = ReactDOM.renderToStaticMarkup(<Html {...htmldata} />);

View File

@ -23,7 +23,7 @@ const MdToggleButtonHover = ({ value, onToggle }) => (
width: 32, width: 32,
height: 32, height: 32,
}} }}
animateThumbStyleHover={n => ({ animateThumbStyleHover={(n) => ({
boxShadow: `0 0 ${2 + (4 * n)}px rgba(0,0,0,.16),0 ${2 + (3 * n)}px ${4 + (8 * n)}px rgba(0,0,0,.32)`, boxShadow: `0 0 ${2 + (4 * n)}px rgba(0,0,0,.16),0 ${2 + (3 * n)}px ${4 + (8 * n)}px rgba(0,0,0,.32)`,
})} })}
/> />

View File

@ -12,7 +12,9 @@ import DownloadButton from './DownloadButton';
import MinecraftTPButton from './MinecraftTPButton'; import MinecraftTPButton from './MinecraftTPButton';
import MinecraftButton from './MinecraftButton'; import MinecraftButton from './MinecraftButton';
const Menu = ({ menuOpen, minecraftname, messages, canvasId }) => ( const Menu = ({
menuOpen, minecraftname, messages, canvasId,
}) => (
<div> <div>
{(menuOpen) ? <SettingsButton /> : null} {(menuOpen) ? <SettingsButton /> : null}
{(menuOpen) ? <LogInButton /> : null} {(menuOpen) ? <LogInButton /> : null}
@ -27,7 +29,9 @@ function mapStateToProps(state: State) {
const { menuOpen } = state.gui; const { menuOpen } = state.gui;
const { minecraftname, messages } = state.user; const { minecraftname, messages } = state.user;
const { canvasId } = state.canvas; const { canvasId } = state.canvas;
return { menuOpen, minecraftname, messages, canvasId }; return {
menuOpen, minecraftname, messages, canvasId,
};
} }
export default connect(mapStateToProps)(Menu); export default connect(mapStateToProps)(Menu);

View File

@ -13,7 +13,7 @@ const MinecraftModal = () => (
<Modal title="PixelPlanet Minecraft Server"> <Modal title="PixelPlanet Minecraft Server">
<p style={{ textAlign: 'center' }}> <p style={{ textAlign: 'center' }}>
<p>You can also place pixels from our Minecraft Server at</p> <p>You can also place pixels from our Minecraft Server at</p>
<p><input type="text" value={'mc.pixelplanet.fun'} readOnly /></p> <p><input type="text" value="mc.pixelplanet.fun" readOnly /></p>
<p>Please Note that the Minecraft Server is down from time to time</p> <p>Please Note that the Minecraft Server is down from time to time</p>
</p> </p>
</Modal> </Modal>

View File

@ -38,5 +38,5 @@ const ModalRoot = ({ modalType, modalProps }) => {
}; };
export default connect( export default connect(
state => state.modal, (state) => state.modal,
)(ModalRoot); )(ModalRoot);

View File

@ -83,13 +83,13 @@ class NewPasswordForm extends React.Component {
} }
return ( return (
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
{errors.map(error => ( {errors.map((error) => (
<p key={error}>Error: {error}</p> <p key={error}>Error: {error}</p>
))} ))}
<input <input
style={inputStyles} style={inputStyles}
value={this.state.email} value={this.state.email}
onChange={evt => this.setState({ email: evt.target.value })} onChange={(evt) => this.setState({ email: evt.target.value })}
type="text" type="text"
placeholder="Email" placeholder="Email"
/> />

View File

@ -5,8 +5,8 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { numberToString } from '../core/utils';
import { FaUser, FaPaintBrush } from 'react-icons/fa'; import { FaUser, FaPaintBrush } from 'react-icons/fa';
import { numberToString } from '../core/utils';
import type { State } from '../reducers'; import type { State } from '../reducers';
@ -14,12 +14,13 @@ import type { State } from '../reducers';
const OnlineBox = ({ online, totalPixels, name }) => ( const OnlineBox = ({ online, totalPixels, name }) => (
<div> <div>
{(online || name) ? {(online || name)
<div className="onlinebox"> ? (
{(online) && <span>{online} <FaUser /></span>} <div className="onlinebox">
{(name != null) && <span>{numberToString(totalPixels)} <FaPaintBrush /></span>} {(online) && <span>{online} <FaUser /></span>}
</div> : null {(name != null) && <span>{numberToString(totalPixels)} <FaPaintBrush /></span>}
} </div>
) : null}
</div> </div>
); );

View File

@ -11,23 +11,28 @@ import { selectColor } from '../actions';
import type { State } from '../reducers'; import type { State } from '../reducers';
const Palette = ({ colors, selectedColor, paletteOpen, compactPalette, select }) => ( const Palette = ({
colors, selectedColor, paletteOpen, compactPalette, select,
}) => (
<div className={`palettebox ${(compactPalette) ? 'compalette' : 'widpalette'}`} id="colors" style={{ display: (paletteOpen) ? 'flex' : 'none' }}> <div className={`palettebox ${(compactPalette) ? 'compalette' : 'widpalette'}`} id="colors" style={{ display: (paletteOpen) ? 'flex' : 'none' }}>
{colors.slice(2).map((color, index) => (<span {colors.slice(2).map((color, index) => (
style={{ backgroundColor: color }} <span
key={index + 2} style={{ backgroundColor: color }}
className={selectedColor === (index + 2) ? 'selected' : 'unselected'} key={index + 2}
color={color} className={selectedColor === (index + 2) ? 'selected' : 'unselected'}
onClick={() => select(index + 2)} color={color}
/>), onClick={() => select(index + 2)}
)} />
))}
</div> </div>
); );
function mapStateToProps(state: State) { function mapStateToProps(state: State) {
const { selectedColor, paletteOpen, compactPalette } = state.gui; const { selectedColor, paletteOpen, compactPalette } = state.gui;
const { palette } = state.canvas; const { palette } = state.canvas;
return { colors: palette.colors, selectedColor, paletteOpen, compactPalette }; return {
colors: palette.colors, selectedColor, paletteOpen, compactPalette,
};
} }
function mapDispatchToProps(dispatch) { function mapDispatchToProps(dispatch) {

View File

@ -10,7 +10,9 @@ import { MdPalette } from 'react-icons/md';
import { toggleOpenPalette } from '../actions'; import { toggleOpenPalette } from '../actions';
const PalselButton = ({ palette, onToggle, selectedColor, paletteOpen }) => ( const PalselButton = ({
palette, onToggle, selectedColor, paletteOpen,
}) => (
<div id="palselbutton" className={`actionbuttons ${(paletteOpen) ? '' : 'pressed'}`} style={{ color: palette.isDark(selectedColor) ? 'white' : 'black', backgroundColor: palette.colors[selectedColor] }} onClick={onToggle}> <div id="palselbutton" className={`actionbuttons ${(paletteOpen) ? '' : 'pressed'}`} style={{ color: palette.isDark(selectedColor) ? 'white' : 'black', backgroundColor: palette.colors[selectedColor] }} onClick={onToggle}>
<MdPalette /> <MdPalette />
</div> </div>

View File

@ -4,7 +4,7 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom/server'; import ReactDOM from 'react-dom/server';
import Html from '../components/Html'; import Html from './Html';
const PasswordReset = ({ name, code }) => ( const PasswordReset = ({ name, code }) => (
<form method="post" action="reset_password"> <form method="post" action="reset_password">

View File

@ -5,7 +5,7 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom/server'; import ReactDOM from 'react-dom/server';
import Html from '../components/Html'; import Html from './Html';
const RedirectionPage = ({ text }) => ( const RedirectionPage = ({ text }) => (
<div> <div>
@ -25,4 +25,3 @@ export function getHtml(description, text) {
const index = `<!doctype html>${ReactDOM.renderToStaticMarkup(<Html {...data} />)}`; const index = `<!doctype html>${ReactDOM.renderToStaticMarkup(<Html {...data} />)}`;
return index; return index;
} }

View File

@ -74,7 +74,9 @@ const dividerStyles = {
}; };
const SettingsItem = ({ title, description, keyBind, value, onToggle }) => ( const SettingsItem = ({
title, description, keyBind, value, onToggle,
}) => (
<div style={itemStyles}> <div style={itemStyles}>
<div style={rowStyles}> <div style={rowStyles}>
<h3 style={titleStyles}>{title} {keyBind && <kbd>{keyBind}</kbd>}</h3> <h3 style={titleStyles}>{title} {keyBind && <kbd>{keyBind}</kbd>}</h3>
@ -154,11 +156,15 @@ function SettingsModal({
function mapStateToProps(state: State) { function mapStateToProps(state: State) {
const { mute, chatNotify } = state.audio; const { mute, chatNotify } = state.audio;
const { showGrid, showPixelNotify, autoZoomIn, compactPalette, isPotato } = state.gui; const {
showGrid, showPixelNotify, autoZoomIn, compactPalette, isPotato,
} = state.gui;
const isMuted = mute; const isMuted = mute;
const isGridShown = showGrid; const isGridShown = showGrid;
const isPixelNotifyShown = showPixelNotify; const isPixelNotifyShown = showPixelNotify;
return { isMuted, isGridShown, isPixelNotifyShown, autoZoomIn, compactPalette, chatNotify, isPotato }; return {
isMuted, isGridShown, isPixelNotifyShown, autoZoomIn, compactPalette, chatNotify, isPotato,
};
} }
function mapDispatchToProps(dispatch) { function mapDispatchToProps(dispatch) {

View File

@ -4,7 +4,9 @@
*/ */
import React from 'react'; import React from 'react';
import { validateEMail, validateName, validatePassword, parseAPIresponse } from '../utils/validation'; import {
validateEMail, validateName, validatePassword, parseAPIresponse,
} from '../utils/validation';
function validate(name, email, password, confirm_password) { function validate(name, email, password, confirm_password) {
const errors = []; const errors = [];
@ -64,7 +66,9 @@ class SignUpForm extends React.Component {
async handleSubmit(e) { async handleSubmit(e) {
e.preventDefault(); e.preventDefault();
const { name, email, password, confirm_password, submitting } = this.state; const {
name, email, password, confirm_password, submitting,
} = this.state;
if (submitting) return; if (submitting) return;
const errors = validate(name, email, password, confirm_password); const errors = validate(name, email, password, confirm_password);
@ -89,34 +93,34 @@ class SignUpForm extends React.Component {
const { errors } = this.state; const { errors } = this.state;
return ( return (
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
{errors.map(error => ( {errors.map((error) => (
<p key={error} className="errormessage">Error: {error}</p> <p key={error} className="errormessage">Error: {error}</p>
))} ))}
<input <input
style={inputStyles} style={inputStyles}
value={this.state.name} value={this.state.name}
onChange={evt => this.setState({ name: evt.target.value })} onChange={(evt) => this.setState({ name: evt.target.value })}
type="text" type="text"
placeholder="Name" placeholder="Name"
/> />
<input <input
style={inputStyles} style={inputStyles}
value={this.state.email} value={this.state.email}
onChange={evt => this.setState({ email: evt.target.value })} onChange={(evt) => this.setState({ email: evt.target.value })}
type="text" type="text"
placeholder="Email" placeholder="Email"
/> />
<input <input
style={inputStyles} style={inputStyles}
value={this.state.password} value={this.state.password}
onChange={evt => this.setState({ password: evt.target.value })} onChange={(evt) => this.setState({ password: evt.target.value })}
type="password" type="password"
placeholder="Password" placeholder="Password"
/> />
<input <input
style={inputStyles} style={inputStyles}
value={this.state.confirm_password} value={this.state.confirm_password}
onChange={evt => this.setState({ confirm_password: evt.target.value })} onChange={(evt) => this.setState({ confirm_password: evt.target.value })}
type="password" type="password"
placeholder="Confirm Password" placeholder="Confirm Password"
/> />

View File

@ -19,14 +19,15 @@ const TotalRankings = ({ totalRanking }) => (
<th>Pixels Today</th> <th>Pixels Today</th>
</tr> </tr>
{ {
totalRanking.map(rank => ( totalRanking.map((rank) => (
<tr> <tr>
<td>{rank.ranking}</td> <td>{rank.ranking}</td>
<td>{rank.name}</td> <td>{rank.name}</td>
<td>{rank.totalPixels}</td> <td>{rank.totalPixels}</td>
<td>{rank.dailyRanking}</td> <td>{rank.dailyRanking}</td>
<td>{rank.dailyTotalPixels}</td> <td>{rank.dailyTotalPixels}</td>
</tr>)) </tr>
))
} }
</table> </table>
</div> </div>

View File

@ -63,28 +63,30 @@ class UserArea extends React.Component {
> Log out</span> | > Log out</span> |
<span <span
className="modallink" className="modallink"
onClick={evt => this.setState({ onClick={(evt) => this.setState({
change_name_extended: true, change_name_extended: true,
change_mail_extended: false, change_mail_extended: false,
change_passwd_extended: false, change_passwd_extended: false,
delete_account_extended: false, delete_account_extended: false,
})} })}
> Change Username</span> | > Change Username</span> |
{(this.props.mailreg) && {(this.props.mailreg)
&& (
<span> <span>
<span <span
className="modallink" className="modallink"
onClick={evt => this.setState({ onClick={(evt) => this.setState({
change_name_extended: false, change_name_extended: false,
change_mail_extended: true, change_mail_extended: true,
change_passwd_extended: false, change_passwd_extended: false,
delete_account_extended: false, delete_account_extended: false,
})} })}
> Change Mail</span> | > Change Mail</span> |
</span>} </span>
)}
<span <span
className="modallink" className="modallink"
onClick={evt => this.setState({ onClick={(evt) => this.setState({
change_name_extended: false, change_name_extended: false,
change_mail_extended: false, change_mail_extended: false,
change_passwd_extended: true, change_passwd_extended: true,
@ -93,7 +95,7 @@ class UserArea extends React.Component {
> Change Password</span> | > Change Password</span> |
<span <span
className="modallink" className="modallink"
onClick={evt => this.setState({ onClick={(evt) => this.setState({
change_name_extended: false, change_name_extended: false,
change_mail_extended: false, change_mail_extended: false,
change_passwd_extended: false, change_passwd_extended: false,
@ -101,26 +103,34 @@ class UserArea extends React.Component {
})} })}
> Delete Account</span> ) > Delete Account</span> )
</p> </p>
{(this.state.change_passwd_extended) && {(this.state.change_passwd_extended)
&& (
<ChangePassword <ChangePassword
mailreg={this.props.mailreg} mailreg={this.props.mailreg}
done={() => { this.props.set_mailreg(true); this.setState({ change_passwd_extended: false }); }} done={() => { this.props.set_mailreg(true); this.setState({ change_passwd_extended: false }); }}
cancel={() => { this.setState({ change_passwd_extended: false }); }} cancel={() => { this.setState({ change_passwd_extended: false }); }}
/>} />
{(this.state.change_name_extended) && )}
{(this.state.change_name_extended)
&& (
<ChangeName <ChangeName
set_name={this.props.set_name} set_name={this.props.set_name}
done={() => { this.setState({ change_name_extended: false }); }} done={() => { this.setState({ change_name_extended: false }); }}
/>} />
{(this.state.change_mail_extended) && )}
{(this.state.change_mail_extended)
&& (
<ChangeMail <ChangeMail
done={() => { this.setState({ change_mail_extended: false }); }} done={() => { this.setState({ change_mail_extended: false }); }}
/>} />
{(this.state.delete_account_extended) && )}
{(this.state.delete_account_extended)
&& (
<DeleteAccount <DeleteAccount
set_name={this.props.set_name} set_name={this.props.set_name}
done={() => { this.setState({ delete_account_extended: false }); }} done={() => { this.setState({ delete_account_extended: false }); }}
/>} />
)}
</p> </p>
); );
} }

View File

@ -11,7 +11,9 @@ import Modal from './Modal';
import type { State } from '../reducers'; import type { State } from '../reducers';
import { showRegisterModal, showForgotPasswordModal, setName, setMailreg, receiveMe } from '../actions'; import {
showRegisterModal, showForgotPasswordModal, setName, setMailreg, receiveMe,
} from '../actions';
import LogInForm from './LogInForm'; import LogInForm from './LogInForm';
import Tabs from './Tabs'; import Tabs from './Tabs';
import UserArea from './UserArea'; import UserArea from './UserArea';
@ -63,23 +65,27 @@ const LogInArea = ({ register, forgot_password, me }) => (
</p> </p>
); );
const UserAreaModal = ({ name, register, forgot_password, doMe, logout, setName, setMailreg }) => ( const UserAreaModal = ({
name, register, forgot_password, doMe, logout, setName, setMailreg,
}) => (
<Modal title="User Area"> <Modal title="User Area">
<p style={{ textAlign: 'center' }}> <p style={{ textAlign: 'center' }}>
{(name === null) ? {(name === null)
<LogInArea register={register} forgot_password={forgot_password} me={doMe} /> : ? <LogInArea register={register} forgot_password={forgot_password} me={doMe} />
<Tabs> : (
<div label="Profile"> <Tabs>
<UserArea <div label="Profile">
logout={logout} <UserArea
set_name={setName} logout={logout}
set_mailreg={setMailreg} set_name={setName}
/> set_mailreg={setMailreg}
</div> />
<div label="Ranking"> </div>
<Rankings /> <div label="Ranking">
</div> <Rankings />
</Tabs>} </div>
</Tabs>
)}
<p>Also join our Discord: <a href="./discord" target="_blank">pixelplanet.fun/discord</a></p> <p>Also join our Discord: <a href="./discord" target="_blank">pixelplanet.fun/discord</a></p>
</p> </p>
</Modal> </Modal>

View File

@ -76,26 +76,28 @@ class UserMessages extends React.Component {
return ( return (
<div> <div>
{(messages.includes('not_verified') && messages.splice(messages.indexOf('not_verified'), 1)) ? {(messages.includes('not_verified') && messages.splice(messages.indexOf('not_verified'), 1))
<p className="usermessages"> ? (
<p className="usermessages">
Please verify your mail address or your account could get deleted after a few days. Please verify your mail address or your account could get deleted after a few days.
{(this.state.verify_answer) ? {(this.state.verify_answer)
<span className="modallink">{this.state.verify_answer}</span> : ? <span className="modallink">{this.state.verify_answer}</span>
<span className="modallink" onClick={this.submit_resend_verify}>Click here to request a new verification mail.</span> : <span className="modallink" onClick={this.submit_resend_verify}>Click here to request a new verification mail.</span>}
} </p>
</p> : null ) : null}
} {(messages.includes('not_mc_verified') && messages.splice(messages.indexOf('not_mc_verified'), 1))
{(messages.includes('not_mc_verified') && messages.splice(messages.indexOf('not_mc_verified'), 1)) ? ? (
<p className="usermessages">You requested to link your mc account {this.props.minecraftname}. <p className="usermessages">You requested to link your mc account {this.props.minecraftname}.
{(this.state.link_answer) ? {(this.state.link_answer)
<span className="modallink">{this.state.link_answer}</span> : ? <span className="modallink">{this.state.link_answer}</span>
<span> : (
<span className="modallink" onClick={() => { this.submit_mc_link(true); }}>Accept</span> or <span className="modallink" onClick={() => { this.submit_mc_link(false); }}>Deny</span>. <span>
</span> <span className="modallink" onClick={() => { this.submit_mc_link(true); }}>Accept</span> or <span className="modallink" onClick={() => { this.submit_mc_link(false); }}>Deny</span>.
} </span>
</p> : null )}
} </p>
{messages.map(message => ( ) : null}
{messages.map((message) => (
<p className="usermessages" key={message} className="message">{message}</p> <p className="usermessages" key={message} className="message">{message}</p>
))} ))}
</div> </div>

View File

@ -2,4 +2,3 @@
export type Index = number; // TODO integer >= 0 export type Index = number; // TODO integer >= 0
export type Cell = [number, number, number]; export type Cell = [number, number, number];

View File

@ -152,4 +152,3 @@ export async function imagemask2Canvas(
} }
logger.info('Imagemask loading done.'); logger.info('Imagemask loading done.');
} }

View File

@ -56,12 +56,12 @@ class Palette {
* @return index of color * @return index of color
*/ */
getIndexOfColor(r: number, g: number, b: number): ColorIndex { getIndexOfColor(r: number, g: number, b: number): ColorIndex {
const rgb = this.rgb; const { rgb } = this;
let i = rgb.length; let i = rgb.length;
while (i >= 0) { while (i >= 0) {
if (rgb[--i] === b && if (rgb[--i] === b
rgb[--i] === g && && rgb[--i] === g
rgb[--i] === r && rgb[--i] === r
) { ) {
return (i / 3); return (i / 3);
} }
@ -75,7 +75,7 @@ class Palette {
* @return ABRG Buffer * @return ABRG Buffer
*/ */
buffer2ABGR(chunkBuffer: Buffer): Uint32Array { buffer2ABGR(chunkBuffer: Buffer): Uint32Array {
const length = chunkBuffer.length; const { length } = chunkBuffer;
const colors = new Uint32Array(length); const colors = new Uint32Array(length);
let value: number; let value: number;
const buffer = chunkBuffer; const buffer = chunkBuffer;
@ -94,7 +94,7 @@ class Palette {
* @return RGB Buffer * @return RGB Buffer
*/ */
buffer2RGB(chunkBuffer: Buffer): Uint8Array { buffer2RGB(chunkBuffer: Buffer): Uint8Array {
const length = chunkBuffer.length; const { length } = chunkBuffer;
const colors = new Uint8Array(length * 3); const colors = new Uint8Array(length * 3);
let color: number; let color: number;
let value: number; let value: number;
@ -167,8 +167,7 @@ export const COLORS_RGB: Uint8Array = new Uint8Array([
25, 25, 115, // darker blue 25, 25, 115, // darker blue
207, 110, 228, // light violette 207, 110, 228, // light violette
130, 0, 128, // violette 130, 0, 128, // violette
], ]);
);
export const COLORS_AMOUNT = COLORS_RGB.length / 3; export const COLORS_AMOUNT = COLORS_RGB.length / 3;
export const COLORS: Array<Color> = new Array(COLORS_AMOUNT); export const COLORS: Array<Color> = new Array(COLORS_AMOUNT);

View File

@ -7,6 +7,7 @@ class Player {
constructor() { constructor() {
this.wait = null; this.wait = null;
} }
setWait(wait) { setWait(wait) {
this.wait = wait; this.wait = wait;
} }

View File

@ -121,7 +121,8 @@ export async function createZoomTileFromChunk(
canvasId: number, canvasId: number,
canvasTileFolder: string, canvasTileFolder: string,
palette: Palette, palette: Palette,
cell: Cell): boolean { cell: Cell,
): boolean {
const [x, y] = cell; const [x, y] = cell;
const maxTiledZoom = getMaxTiledZoom(canvasSize); const maxTiledZoom = getMaxTiledZoom(canvasSize);
const tileRGBBuffer = new Uint8Array( const tileRGBBuffer = new Uint8Array(
@ -162,8 +163,7 @@ export async function createZoomTileFromChunk(
height: TILE_SIZE * TILE_ZOOM_LEVEL, height: TILE_SIZE * TILE_ZOOM_LEVEL,
channels: 3, channels: 3,
}, },
}, })
)
.resize(TILE_SIZE) .resize(TILE_SIZE)
.png({ options: { compressionLevel: 6 } }) .png({ options: { compressionLevel: 6 } })
.toFile(filename); .toFile(filename);
@ -212,7 +212,8 @@ export async function createZoomedTile(
const filename = tileFileName(canvasTileFolder, [z, x, y]); const filename = tileFileName(canvasTileFolder, [z, x, y]);
await sharp( await sharp(
Buffer.from( Buffer.from(
tileRGBBuffer.buffer), { tileRGBBuffer.buffer,
), {
raw: { raw: {
width: TILE_SIZE * TILE_ZOOM_LEVEL, width: TILE_SIZE * TILE_ZOOM_LEVEL,
height: TILE_SIZE * TILE_ZOOM_LEVEL, height: TILE_SIZE * TILE_ZOOM_LEVEL,
@ -255,8 +256,7 @@ export async function createEmptyTile(
height: TILE_SIZE, height: TILE_SIZE,
channels: 3, channels: 3,
}, },
}, })
)
.png({ options: { compressionLevel: 6 } }) .png({ options: { compressionLevel: 6 } })
.toFile(filename); .toFile(filename);
logger.info(`Tiling: Created empty tile at ${filename}`); logger.info(`Tiling: Created empty tile at ${filename}`);
@ -422,4 +422,3 @@ export async function initializeTiles(
`Tiling: Elapsed Time: ${Math.round((Date.now() - startTime) / 1000)} for canvas${canvasId}`, `Tiling: Elapsed Time: ${Math.round((Date.now() - startTime) / 1000)} for canvas${canvasId}`,
); );
} }

View File

@ -32,8 +32,8 @@ export const DISCORD_INVITE = process.env.DISCORD_INVITE || 'https://discordapp.
// Accounts // Accounts
export const APISOCKET_KEY = process.env.APISOCKET_KEY || 'changethis'; export const APISOCKET_KEY = process.env.APISOCKET_KEY || 'changethis';
// Comma seperated list of user ids of Admins // Comma seperated list of user ids of Admins
export const ADMIN_IDS = (process.env.ADMIN_IDS) ? export const ADMIN_IDS = (process.env.ADMIN_IDS)
process.env.ADMIN_IDS.split(',').map(z => parseInt(z, 10)) : []; ? process.env.ADMIN_IDS.split(',').map((z) => parseInt(z, 10)) : [];
export const analytics = { export const analytics = {
// https://analytics.google.com/ // https://analytics.google.com/
@ -83,4 +83,3 @@ export const RECAPTCHA_SITEKEY = process.env.RECAPTCHA_SITEKEY || false;
export const RECAPTCHA_TIME = parseInt(process.env.RECAPTCHA_TIME, 10) || 30; export const RECAPTCHA_TIME = parseInt(process.env.RECAPTCHA_TIME, 10) || 30;
export const SESSION_SECRET = process.env.SESSION_SECRET || 'dummy'; export const SESSION_SECRET = process.env.SESSION_SECRET || 'dummy';

View File

@ -88,4 +88,3 @@ export const MIN_COOLDOWN = 30 * SECOND; */
export const BLANK_COOLDOWN = 3 * SECOND; export const BLANK_COOLDOWN = 3 * SECOND;
export const MIN_COOLDOWN = 15 * SECOND; export const MIN_COOLDOWN = 15 * SECOND;

View File

@ -58,8 +58,8 @@ async function draw(
const canvasMaxXY = canvas.size / 2; const canvasMaxXY = canvas.size / 2;
const canvasMinXY = -canvasMaxXY; const canvasMinXY = -canvasMaxXY;
if (x < canvasMinXY || y < canvasMinXY || if (x < canvasMinXY || y < canvasMinXY
x >= canvasMaxXY || y >= canvasMaxXY) { || x >= canvasMaxXY || y >= canvasMaxXY) {
return { return {
error: 'Coordinates not withing canvas', error: 'Coordinates not withing canvas',
success: false, success: false,

View File

@ -11,9 +11,9 @@ function forceGC() {
if (global.gc) { if (global.gc) {
global.gc(); global.gc();
} else { } else {
logger.warn('Garbage collection unavailable. ' + logger.warn('Garbage collection unavailable. '
'Pass --expose-gc when launching node to enable forced garbage ' + + 'Pass --expose-gc when launching node to enable forced garbage '
'collection.'); + 'collection.');
} }
} }

View File

@ -2,8 +2,8 @@
* @flow * @flow
* */ * */
import fetch from '../utils/proxiedFetch.js';
import IP from 'ip'; import IP from 'ip';
import fetch from '../utils/proxiedFetch.js';
import redis from '../data/redis'; import redis from '../data/redis';
import { Blacklist, Whitelist } from '../data/models'; import { Blacklist, Whitelist } from '../data/models';

View File

@ -4,13 +4,13 @@
*/ */
// must use require for arguments // must use require for arguments
import Sequelize from 'sequelize';
import logger from './logger'; import logger from './logger';
import { HOUR, MINUTE } from './constants'; import { HOUR, MINUTE } from './constants';
import { HOSTURL } from './config'; import { HOSTURL } from './config';
import { DailyCron, HourlyCron } from '../utils/cron'; import { DailyCron, HourlyCron } from '../utils/cron';
import Sequelize from 'sequelize';
import RegUser from '../data/models/RegUser'; import RegUser from '../data/models/RegUser';
const sendmail = require('sendmail')({ silent: true }); const sendmail = require('sendmail')({ silent: true });

View File

@ -11,7 +11,9 @@ import canvases from '../canvases.json';
export default async function getMe(user) { export default async function getMe(user) {
const userdata = user.getUserData(); const userdata = user.getUserData();
// sanitize data // sanitize data
const { name, mailVerified, minecraftname, mcVerified } = userdata; const {
name, mailVerified, minecraftname, mcVerified,
} = userdata;
if (!name) userdata.name = null; if (!name) userdata.name = null;
const messages = []; const messages = [];
if (name && !mailVerified) { if (name && !mailVerified) {
@ -30,4 +32,3 @@ export default async function getMe(user) {
return userdata; return userdata;
} }

View File

@ -7,7 +7,7 @@ import Model from '../data/sequelize';
import RegUser from '../data/models/RegUser'; import RegUser from '../data/models/RegUser';
import logger from './logger'; import logger from './logger';
import { HOUR, MINUTE } from '../core/constants'; import { HOUR, MINUTE } from './constants';
import { DailyCron } from '../utils/cron'; import { DailyCron } from '../utils/cron';
class Ranks { class Ranks {

View File

@ -12,12 +12,16 @@ import canvases from '../canvases.json';
import Palette from './Palette'; import Palette from './Palette';
import { TILE_FOLDER } from './config'; import { TILE_FOLDER } from './config';
import { TILE_SIZE, import {
TILE_ZOOM_LEVEL } from './constants'; TILE_SIZE,
import { createZoomTileFromChunk, TILE_ZOOM_LEVEL,
} from './constants';
import {
createZoomTileFromChunk,
createZoomedTile, createZoomedTile,
createTexture, createTexture,
initializeTiles } from './Tile'; initializeTiles,
} from './Tile';
import { mod, getChunkOfPixel, getMaxTiledZoom } from './utils'; import { mod, getChunkOfPixel, getMaxTiledZoom } from './utils';
@ -77,7 +81,7 @@ class CanvasUpdater {
if (zoom === 0) { if (zoom === 0) {
createTexture(this.id, this.canvas.size, this.canvasTileFolder, this.palette); createTexture(this.id, this.canvas.size, this.canvasTileFolder, this.palette);
} else { } else {
const [ucx, ucy] = [cx, cy].map(z => Math.floor(z / 4)); const [ucx, ucy] = [cx, cy].map((z) => Math.floor(z / 4));
const upperTile = ucx + ucy * (TILE_ZOOM_LEVEL ** (zoom - 1)); const upperTile = ucx + ucy * (TILE_ZOOM_LEVEL ** (zoom - 1));
const upperQueue = this.TileLoadingQueues[zoom - 1]; const upperQueue = this.TileLoadingQueues[zoom - 1];
if (~upperQueue.indexOf(upperTile)) return; if (~upperQueue.indexOf(upperTile)) return;
@ -95,7 +99,7 @@ class CanvasUpdater {
const queue = this.TileLoadingQueues[Math.max(this.maxTiledZoom - 1, 0)]; const queue = this.TileLoadingQueues[Math.max(this.maxTiledZoom - 1, 0)];
if (typeof queue === 'undefined') return; if (typeof queue === 'undefined') return;
const [cx, cy] = chunk.map(z => Math.floor(z / 4)); const [cx, cy] = chunk.map((z) => Math.floor(z / 4));
const chunkOffset = cx + cy * this.firstZoomtileWidth; const chunkOffset = cx + cy * this.firstZoomtileWidth;
if (~queue.indexOf(chunkOffset)) return; if (~queue.indexOf(chunkOffset)) return;
queue.push(chunkOffset); queue.push(chunkOffset);
@ -166,4 +170,3 @@ export function startAllCanvasLoops() {
CanvasUpdaters[ids[i]] = updater; CanvasUpdaters[ids[i]] = updater;
} }
} }

View File

@ -18,7 +18,7 @@ export function mod(n: number, m: number): number {
export function sum(values: Array<number>): number { export function sum(values: Array<number>): number {
let total = 0; let total = 0;
// TODO map reduce // TODO map reduce
values.forEach(value => total += value); values.forEach((value) => total += value);
return total; return total;
} }
@ -31,12 +31,12 @@ export function clamp(n: number, min: number, max: number): number {
} }
export function getChunkOfPixel(pixel: Cell, canvasSize: number = null): Cell { export function getChunkOfPixel(pixel: Cell, canvasSize: number = null): Cell {
const target = pixel.map(x => Math.floor((x + (canvasSize / 2)) / TILE_SIZE)); const target = pixel.map((x) => Math.floor((x + (canvasSize / 2)) / TILE_SIZE));
return target; return target;
} }
export function getTileOfPixel(tileScale: number, pixel: Cell, canvasSize: number = null): Cell { export function getTileOfPixel(tileScale: number, pixel: Cell, canvasSize: number = null): Cell {
const target = pixel.map(x => Math.floor((x + canvasSize / 2) / TILE_SIZE * tileScale)); const target = pixel.map((x) => Math.floor((x + canvasSize / 2) / TILE_SIZE * tileScale));
return target; return target;
} }
@ -92,7 +92,7 @@ export function getPixelFromChunkOffset(
export function getCellInsideChunk(pixel: Cell): Cell { export function getCellInsideChunk(pixel: Cell): Cell {
// TODO assert is positive! // TODO assert is positive!
return pixel.map(x => mod(x, TILE_SIZE)); return pixel.map((x) => mod(x, TILE_SIZE));
} }
export function screenToWorld( export function screenToWorld(
@ -172,9 +172,9 @@ export function numberToString(num: number): string {
while (postfixNum < postfix.length) { while (postfixNum < postfix.length) {
if (num < 10000) { if (num < 10000) {
return `${Math.floor(num / 1000)}.${Math.floor((num % 1000) / 10)}${postfix[postfixNum]}`; return `${Math.floor(num / 1000)}.${Math.floor((num % 1000) / 10)}${postfix[postfixNum]}`;
} else if (num < 100000) { } if (num < 100000) {
return `${Math.floor(num / 1000)}.${Math.floor((num % 1000) / 100)}${postfix[postfixNum]}`; return `${Math.floor(num / 1000)}.${Math.floor((num % 1000) / 100)}${postfix[postfixNum]}`;
} else if (num < 1000000) { } if (num < 1000000) {
return Math.floor(num / 1000) + postfix[postfixNum]; return Math.floor(num / 1000) + postfix[postfixNum];
} }
postfixNum += 1; postfixNum += 1;
@ -186,9 +186,9 @@ export function numberToString(num: number): string {
export function numberToStringFull(num: number): string { export function numberToStringFull(num: number): string {
if (num < 0) { if (num < 0) {
return `${num} :-(`; return `${num} :-(`;
} else if (num < 1000) { } if (num < 1000) {
return num; return num;
} else if (num < 1000000) { } if (num < 1000000) {
return `${Math.floor(num / 1000)}.${(`00${num % 1000}`).slice(-3)}`; return `${Math.floor(num / 1000)}.${(`00${num % 1000}`).slice(-3)}`;
} }

View File

@ -24,8 +24,7 @@ class RedisCanvas {
} }
static async setChunk(i: number, j: number, chunk: Uint8Array, static async setChunk(i: number, j: number, chunk: Uint8Array,
canvasId: number, canvasId: number) {
) {
if (chunk.length !== TILE_SIZE * TILE_SIZE) { if (chunk.length !== TILE_SIZE * TILE_SIZE) {
logger.error(`Tried to set chunk with invalid length ${chunk.length}!`); logger.error(`Tried to set chunk with invalid length ${chunk.length}!`);
return false; return false;

View File

@ -7,8 +7,8 @@
*/ */
import DataType from 'sequelize'; import DataType from 'sequelize';
import Model from '../sequelize';
import bcrypt from 'bcrypt'; import bcrypt from 'bcrypt';
import Model from '../sequelize';
import { generateHash } from '../../utils/hash'; import { generateHash } from '../../utils/hash';

View File

@ -7,10 +7,10 @@
* @flow * @flow
* */ * */
import Sequelize from 'sequelize';
import redis from '../redis'; import redis from '../redis';
import { randomDice } from '../../utils/random'; import { randomDice } from '../../utils/random';
import logger from '../../core/logger'; import logger from '../../core/logger';
import Sequelize from 'sequelize';
import Model from '../sequelize'; import Model from '../sequelize';
import RegUser from './RegUser'; import RegUser from './RegUser';
@ -58,7 +58,7 @@ class User {
} }
async incrementPixelcount(): Promise<boolean> { async incrementPixelcount(): Promise<boolean> {
const id = this.id; const { id } = this;
if (!id) return false; if (!id) return false;
if (this.isAdmin()) return false; if (this.isAdmin()) return false;
try { try {
@ -75,7 +75,7 @@ class User {
} }
async getTotalPixels(): Promise<number> { async getTotalPixels(): Promise<number> {
const id = this.id; const { id } = this;
if (!id) return 0; if (!id) return 0;
if (this.isAdmin()) return 100000; if (this.isAdmin()) return 100000;
if (this.regUser) { if (this.regUser) {
@ -83,7 +83,9 @@ class User {
} }
try { try {
const userq = await Model.query('SELECT totalPixels FROM Users WHERE id = $1', const userq = await Model.query('SELECT totalPixels FROM Users WHERE id = $1',
{ bind: [id], type: Sequelize.QueryTypes.SELECT, raw: true, plain: true }); {
bind: [id], type: Sequelize.QueryTypes.SELECT, raw: true, plain: true,
});
return userq.totalPixels; return userq.totalPixels;
} catch (err) { } catch (err) {
return 0; return 0;

View File

@ -12,4 +12,6 @@ function sync(...args) {
} }
export default { sync }; export default { sync };
export { Whitelist, Blacklist, User, RegUser }; export {
Whitelist, Blacklist, User, RegUser,
};

View File

@ -6,7 +6,9 @@
import Sequelize from 'sequelize'; import Sequelize from 'sequelize';
import logging from '../core/logger'; import logging from '../core/logger';
import { MYSQL_HOST, MYSQL_DATABASE, MYSQL_USER, MYSQL_PW } from '../core/config'; import {
MYSQL_HOST, MYSQL_DATABASE, MYSQL_USER, MYSQL_PW,
} from '../core/config';
const sequelize = new Sequelize(MYSQL_DATABASE, MYSQL_USER, MYSQL_PW, { const sequelize = new Sequelize(MYSQL_DATABASE, MYSQL_USER, MYSQL_PW, {
host: MYSQL_HOST, host: MYSQL_HOST,

View File

@ -16,10 +16,10 @@ function checkMaterial(object) {
function parseHashCoords() { function parseHashCoords() {
try { try {
const hash = window.location.hash; const { hash } = window.location;
const array = hash.substring(1).split(','); const array = hash.substring(1).split(',');
const ident = array.shift(); const ident = array.shift();
const [id, size, x, y] = array.map(z => parseInt(z, 10)); const [id, size, x, y] = array.map((z) => parseInt(z, 10));
if (!ident || isNaN(x) || isNaN(y) || isNaN(id) || isNaN(size)) { if (!ident || isNaN(x) || isNaN(y) || isNaN(id) || isNaN(size)) {
throw new Error('NaN'); throw new Error('NaN');
} }
@ -96,7 +96,7 @@ document.addEventListener('DOMContentLoaded', () => {
const loader = new GLTFLoader(); const loader = new GLTFLoader();
loader.load('./assets3d/globe.glb', (glb) => { loader.load('./assets3d/globe.glb', (glb) => {
scene.add(glb.scene); scene.add(glb.scene);
const children = glb.scene.children; const { children } = glb.scene;
for (let cnt = 0; cnt < children.length; cnt++) { for (let cnt = 0; cnt < children.length; cnt++) {
if (checkMaterial(children[cnt])) { if (checkMaterial(children[cnt])) {
object = children[cnt]; object = children[cnt];
@ -114,7 +114,7 @@ document.addEventListener('DOMContentLoaded', () => {
rotateToCoords(canvasSize, object, [x, y]); rotateToCoords(canvasSize, object, [x, y]);
controls = createControls(); controls = createControls();
render(); render();
document.getElementById('loading').style.display = "none"; document.getElementById('loading').style.display = 'none';
}, () => { }, () => {
// console.log(`${xhr.loaded} loaded`); // console.log(`${xhr.loaded} loaded`);
}, () => { }, () => {

View File

@ -3,7 +3,8 @@
import type { Action } from '../actions/types'; import type { Action } from '../actions/types';
import type { Cell } from '../core/Cell'; import type { Cell } from '../core/Cell';
import Palette from '../core/Palette'; import Palette from '../core/Palette';
import { getMaxTiledZoom, import {
getMaxTiledZoom,
getChunkOfPixel, getChunkOfPixel,
getCellInsideChunk, getCellInsideChunk,
clamp, clamp,
@ -51,7 +52,7 @@ function getGivenCoords() {
* @return view, viewscale and scale for state * @return view, viewscale and scale for state
*/ */
function getViewFromURL(canvases: Object) { function getViewFromURL(canvases: Object) {
const hash: string = window.location.hash; const { hash } = window.location;
try { try {
const almost = hash.substring(1) const almost = hash.substring(1)
.split(','); .split(',');
@ -59,8 +60,8 @@ function getViewFromURL(canvases: Object) {
const canvasIdent = almost[0]; const canvasIdent = almost[0];
// will be null if not in DEFAULT_CANVASES // will be null if not in DEFAULT_CANVASES
const canvasId = getIdFromObject(canvases, almost[0]); const canvasId = getIdFromObject(canvases, almost[0]);
const colors = (canvasId !== null) ? const colors = (canvasId !== null)
canvases[canvasId].colors : canvases[DEFAULT_CANVAS_ID].colors; ? canvases[canvasId].colors : canvases[DEFAULT_CANVAS_ID].colors;
const canvasSize = (canvasId !== null) ? canvases[canvasId].size : 1024; const canvasSize = (canvasId !== null) ? canvases[canvasId].size : 1024;
const x = parseInt(almost[1], 10); const x = parseInt(almost[1], 10);
@ -115,7 +116,9 @@ export default function gui(
): CanvasState { ): CanvasState {
switch (action.type) { switch (action.type) {
case 'PLACE_PIXEL': { case 'PLACE_PIXEL': {
const { chunks, canvasMaxTiledZoom, palette, canvasSize } = state; const {
chunks, canvasMaxTiledZoom, palette, canvasSize,
} = state;
const { coordinates, color } = action; const { coordinates, color } = action;
const [cx, cy] = getChunkOfPixel(coordinates, canvasSize); const [cx, cy] = getChunkOfPixel(coordinates, canvasSize);
@ -159,7 +162,7 @@ export default function gui(
} }
const canvasMinXY = -canvasSize / 2; const canvasMinXY = -canvasSize / 2;
const canvasMaxXY = canvasSize / 2 - 1; const canvasMaxXY = canvasSize / 2 - 1;
view = [hx, hy].map(z => clamp(z, canvasMinXY, canvasMaxXY)); view = [hx, hy].map((z) => clamp(z, canvasMinXY, canvasMaxXY));
return { return {
...state, ...state,
view, view,
@ -173,7 +176,7 @@ export default function gui(
const { canvasSize } = state; const { canvasSize } = state;
const canvasMinXY = -canvasSize / 2; const canvasMinXY = -canvasSize / 2;
const canvasMaxXY = canvasSize / 2 - 1; const canvasMaxXY = canvasSize / 2 - 1;
const newview = view.map(z => clamp(z, canvasMinXY, canvasMaxXY)); const newview = view.map((z) => clamp(z, canvasMinXY, canvasMaxXY));
return { return {
...state, ...state,
view: newview, view: newview,
@ -209,12 +212,14 @@ export default function gui(
} }
case 'REQUEST_BIG_CHUNK': { case 'REQUEST_BIG_CHUNK': {
const { palette, chunks, fetchs, requested } = state; const {
palette, chunks, fetchs, requested,
} = state;
const { center } = action; const { center } = action;
const chunkRGB = new ChunkRGB(palette, center); const chunkRGB = new ChunkRGB(palette, center);
// chunkRGB.preLoad(chunks); // chunkRGB.preLoad(chunks);
const key = chunkRGB.key; const { key } = chunkRGB;
chunks.set(key, chunkRGB); chunks.set(key, chunkRGB);
requested.add(key); requested.add(key);
@ -281,7 +286,9 @@ export default function gui(
const { chunks, canvasMaxTiledZoom } = state; const { chunks, canvasMaxTiledZoom } = state;
// i, j: Coordinates of chunk // i, j: Coordinates of chunk
// offset: Offset of pixel within said chunk // offset: Offset of pixel within said chunk
const { i, j, offset, color } = action; const {
i, j, offset, color,
} = action;
const key = ChunkRGB.getKey(canvasMaxTiledZoom, i, j); const key = ChunkRGB.getKey(canvasMaxTiledZoom, i, j);
const chunk = chunks.get(key); const chunk = chunks.get(key);

View File

@ -40,7 +40,7 @@ router.use(session);
* (cut IPv6 to subnet to prevent abuse) * (cut IPv6 to subnet to prevent abuse)
*/ */
router.use(async (req, res, next) => { router.use(async (req, res, next) => {
const session = req.session; const { session } = req;
const id = (session.passport && session.passport.user) ? session.passport.user : null; const id = (session.passport && session.passport.user) ? session.passport.user : null;
const ip = await getIPFromRequest(req); const ip = await getIPFromRequest(req);
const trueIp = ip || '0.0.0.1'; const trueIp = ip || '0.0.0.1';

View File

@ -37,7 +37,7 @@ export default async (req: Request, res: Response) => {
return; return;
} }
const minecraftid = user.regUser.minecraftid; const { minecraftid } = user.regUser;
if (!minecraftid) { if (!minecraftid) {
res.status(400); res.status(400);
res.json({ res.json({

View File

@ -33,8 +33,7 @@ router.use('/',
total: 24, total: 24,
expire: 5 * MINUTE, expire: 5 * MINUTE,
skipHeaders: true, skipHeaders: true,
}), }));
);
/* /*

View File

@ -181,7 +181,9 @@ class APISocketServer extends EventEmitter {
} }
const user = this.mc.minecraftid2User(minecraftid); const user = this.mc.minecraftid2User(minecraftid);
user.ip = ip; user.ip = ip;
const { error, success, waitSeconds, coolDownSeconds } = await drawUnsafe(user, 0, x, y, clr); const {
error, success, waitSeconds, coolDownSeconds,
} = await drawUnsafe(user, 0, x, y, clr);
ws.send(JSON.stringify([ ws.send(JSON.stringify([
'retpxl', 'retpxl',
(minecraftid) || ip, (minecraftid) || ip,

View File

@ -175,8 +175,8 @@ class ProtocolClient extends EventEmitter {
this.isConnected = false; this.isConnected = false;
// reconnect in 1s if last connect was longer than 7s ago, else 5s // reconnect in 1s if last connect was longer than 7s ago, else 5s
const timeout = (this.timeConnected < Date.now() - 7000) ? 1000 : 5000; const timeout = (this.timeConnected < Date.now() - 7000) ? 1000 : 5000;
console.warn('Socket is closed. ' + console.warn('Socket is closed. '
`Reconnect will be attempted in ${timeout} ms.`, e.reason); + `Reconnect will be attempted in ${timeout} ms.`, e.reason);
setTimeout(() => this.connect(), 5000); setTimeout(() => this.connect(), 5000);
} }

View File

@ -226,7 +226,7 @@ class SocketServer extends EventEmitter {
break; break;
case RegisterMultipleChunks.OP_CODE: case RegisterMultipleChunks.OP_CODE:
this.deleteAllChunks(ws); this.deleteAllChunks(ws);
const length = buffer.length; const { length } = buffer;
let posu = 2; let posu = 2;
while (posu < length) { while (posu < length) {
const chunkid = buffer[posu++] | buffer[posu++] << 8; const chunkid = buffer[posu++] | buffer[posu++] << 8;

View File

@ -25,7 +25,9 @@ export default {
const j = data.getInt16(3); const j = data.getInt16(3);
const offset = data.getUint16(5); const offset = data.getUint16(5);
const color = data.getUint8(7); const color = data.getUint8(7);
return { i, j, offset, color }; return {
i, j, offset, color,
};
}, },
dehydrate(i, j, offset, color): Buffer { dehydrate(i, j, offset, color): Buffer {
// SERVER // SERVER

View File

@ -19,7 +19,7 @@ router.use(session);
* (cut IPv6 to subnet to prevent abuse) * (cut IPv6 to subnet to prevent abuse)
*/ */
router.use(async (req, res, next) => { router.use(async (req, res, next) => {
const session = req.session; const { session } = req;
const ip = await getIPFromRequest(req); const ip = await getIPFromRequest(req);
const trueIp = ip || '0.0.0.1'; const trueIp = ip || '0.0.0.1';
req.trueIp = trueIp; req.trueIp = trueIp;

View File

@ -111,7 +111,7 @@ startOnlineCounterBroadcast();
* Get hooked up to httpServer and routes to the right socket * Get hooked up to httpServer and routes to the right socket
*/ */
export function wsupgrade(request, socket, head) { export function wsupgrade(request, socket, head) {
const pathname = url.parse(request.url).pathname; const { pathname } = url.parse(request.url);
if (pathname === '/ws') { if (pathname === '/ws') {
usersocket.wss.handleUpgrade(request, socket, head, (ws) => { usersocket.wss.handleUpgrade(request, socket, head, (ws) => {

View File

@ -11,7 +11,7 @@
import { playAd } from '../ui/ads'; import { playAd } from '../ui/ads';
export default store => next => (action) => { export default (store) => (next) => (action) => {
switch (action.type) { switch (action.type) {
case 'PLACE_PIXEL': { case 'PLACE_PIXEL': {
// wait 1 second // wait 1 second

View File

@ -22,7 +22,7 @@
import track from './track'; import track from './track';
export default store => next => (action) => { export default (store) => (next) => (action) => {
track(action); track(action);
return next(action); return next(action);
}; };

View File

@ -20,7 +20,6 @@
* DEALINGS IN THE SOFTWARE * DEALINGS IN THE SOFTWARE
*/ */
export default store => next => action => export default (store) => (next) => (action) => (Array.isArray(action)
(Array.isArray(action) ? action.map(next)
? action.map(next) : next(action));
: next(action));

View File

@ -10,7 +10,7 @@ const COLORS_AMOUNT = 32;
const AudioContext = window.AudioContext || window.webkitAudioContext; const AudioContext = window.AudioContext || window.webkitAudioContext;
const context = new AudioContext(); const context = new AudioContext();
export default store => next => (action) => { export default (store) => (next) => (action) => {
const { mute, chatNotify } = store.getState().audio; const { mute, chatNotify } = store.getState().audio;
switch (action.type) { switch (action.type) {
@ -85,7 +85,7 @@ export default store => next => (action) => {
break; break;
} }
case 'PLACE_PIXEL' : { case 'PLACE_PIXEL': {
if (mute) break; if (mute) break;
const { color } = action; const { color } = action;
const clrFreq = 100 + Math.log(color / COLORS_AMOUNT + 1) * 300; const clrFreq = 100 + Math.log(color / COLORS_AMOUNT + 1) * 300;
@ -107,7 +107,7 @@ export default store => next => (action) => {
break; break;
} }
case 'COOLDOWN_END' : { case 'COOLDOWN_END': {
if (mute) break; if (mute) break;
const oscillatorNode = context.createOscillator(); const oscillatorNode = context.createOscillator();
const gainNode = context.createGain(); const gainNode = context.createGain();

View File

@ -14,7 +14,7 @@ function onDenied() {
} }
export default store => next => (action) => { export default (store) => (next) => (action) => {
if (!Push.isSupported) return next(action); if (!Push.isSupported) return next(action);
switch (action.type) { switch (action.type) {

View File

@ -25,7 +25,6 @@ function warn(error) {
throw error; // To let the caller handle the rejection throw error; // To let the caller handle the rejection
} }
export default store => next => action => export default (store) => (next) => (action) => (typeof action.then === 'function'
(typeof action.then === 'function' ? Promise.resolve(action).then(next, warn)
? Promise.resolve(action).then(next, warn) : next(action));
: next(action));

View File

@ -12,7 +12,7 @@ const TITLE = 'PixelPlanet.fun';
let lastTitle = null; let lastTitle = null;
export default store => next => (action) => { export default (store) => (next) => (action) => {
switch (action.type) { switch (action.type) {
case 'COOLDOWN_SET': { case 'COOLDOWN_SET': {
const { coolDown } = store.getState().user; const { coolDown } = store.getState().user;
@ -34,4 +34,3 @@ export default store => next => (action) => {
return next(action); return next(action);
}; };

View File

@ -75,7 +75,7 @@ class PixelNotify {
continue; continue;
} }
const [sx, sy] = worldToScreen(state, $viewport, [x, y]) const [sx, sy] = worldToScreen(state, $viewport, [x, y])
.map(x => x + this.scale / 2); .map((x) => x + this.scale / 2);
const notRadius = timePasseded / PixelNotify.NOTIFICATION_TIME * this.notificationRadius; const notRadius = timePasseded / PixelNotify.NOTIFICATION_TIME * this.notificationRadius;
const circleScale = notRadius / 100; const circleScale = notRadius / 100;

View File

@ -95,7 +95,7 @@ class Renderer {
const [x, y] = getPixelFromChunkOffset(i, j, offset, this.canvasSize); const [x, y] = getPixelFromChunkOffset(i, j, offset, this.canvasSize);
const [canX, canY] = this.centerChunk const [canX, canY] = this.centerChunk
.map(z => (z + 0.5) * TILE_SIZE - this.canvasSize / 2); .map((z) => (z + 0.5) * TILE_SIZE - this.canvasSize / 2);
const px = ((x - canX) * scale) + (CANVAS_WIDTH / 2); const px = ((x - canX) * scale) + (CANVAS_WIDTH / 2);
const py = ((y - canY) * scale) + (CANVAS_HEIGHT / 2); const py = ((y - canY) * scale) + (CANVAS_HEIGHT / 2);
// if not part of our current canvas, do not render // if not part of our current canvas, do not render
@ -118,10 +118,8 @@ class Renderer {
return false; return false;
} }
const { width, height } = this.viewport; const { width, height } = this.viewport;
const CHUNK_RENDER_RADIUS_X = const CHUNK_RENDER_RADIUS_X = Math.ceil(width / TILE_SIZE / 2 / this.relScale);
Math.ceil(width / TILE_SIZE / 2 / this.relScale); const CHUNK_RENDER_RADIUS_Y = Math.ceil(height / TILE_SIZE / 2 / this.relScale);
const CHUNK_RENDER_RADIUS_Y =
Math.ceil(height / TILE_SIZE / 2 / this.relScale);
const [xc, yc] = this.centerChunk; const [xc, yc] = this.centerChunk;
if (Math.abs(cx - xc) if (Math.abs(cx - xc)
<= CHUNK_RENDER_RADIUS_X && Math.abs(cy - yc) <= CHUNK_RENDER_RADIUS_X && Math.abs(cy - yc)
@ -141,8 +139,10 @@ class Renderer {
const context = this.canvas.getContext('2d'); const context = this.canvas.getContext('2d');
if (!context) return; if (!context) return;
const { centerChunk: chunkPosition, scale, tiledScale, tiledZoom } = this; const {
let relScale = this.relScale; centerChunk: chunkPosition, scale, tiledScale, tiledZoom,
} = this;
let { relScale } = this;
// clear rect is just needed for Google Chrome, else it would flash regularly // clear rect is just needed for Google Chrome, else it would flash regularly
context.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); context.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
@ -234,7 +234,7 @@ class Renderer {
render() { render() {
const viewport = this.viewport; const { viewport } = this;
const state: State = store.getState(); const state: State = store.getState();
const { const {
showGrid, showGrid,
@ -296,14 +296,14 @@ class Renderer {
// note: this.hover is used to, to render without the placeholder one last time when cursor leaves window // note: this.hover is used to, to render without the placeholder one last time when cursor leaves window
} else if ( } else if (
// no full rerender // no full rerender
!doRenderCanvas && !doRenderCanvas
// no render placeholder under cursor // no render placeholder under cursor
!doRenderPlaceholder && && !doRenderPlaceholder
!doRenderPotatoPlaceholder && && !doRenderPotatoPlaceholder
// no pixelnotification // no pixelnotification
!doRenderPixelnotify && && !doRenderPixelnotify
// no forced just-viewscale render (i.e. when just a pixel got set) // no forced just-viewscale render (i.e. when just a pixel got set)
!this.forceNextSubrender && !this.forceNextSubrender
) { ) {
return; return;
} }
@ -332,14 +332,12 @@ class Renderer {
viewportCtx.scale(viewscale, viewscale); viewportCtx.scale(viewscale, viewscale);
viewportCtx.drawImage(this.canvas, viewportCtx.drawImage(this.canvas,
width / 2 / viewscale - CANVAS_WIDTH / 2 + ((cx + 0.5) * TILE_SIZE - canvasCenter - x), width / 2 / viewscale - CANVAS_WIDTH / 2 + ((cx + 0.5) * TILE_SIZE - canvasCenter - x),
height / 2 / viewscale - CANVAS_HEIGHT / 2 + ((cy + 0.5) * TILE_SIZE - canvasCenter - y), height / 2 / viewscale - CANVAS_HEIGHT / 2 + ((cy + 0.5) * TILE_SIZE - canvasCenter - y));
);
viewportCtx.restore(); viewportCtx.restore();
} else { } else {
viewportCtx.drawImage(this.canvas, viewportCtx.drawImage(this.canvas,
Math.floor(width / 2 - CANVAS_WIDTH / 2 + ((cx + 0.5) * TILE_SIZE / this.tiledScale - canvasCenter - x) * viewscale), Math.floor(width / 2 - CANVAS_WIDTH / 2 + ((cx + 0.5) * TILE_SIZE / this.tiledScale - canvasCenter - x) * viewscale),
Math.floor(height / 2 - CANVAS_HEIGHT / 2 + ((cy + 0.5) * TILE_SIZE / this.tiledScale - canvasCenter - y) * viewscale), Math.floor(height / 2 - CANVAS_HEIGHT / 2 + ((cy + 0.5) * TILE_SIZE / this.tiledScale - canvasCenter - y) * viewscale));
);
} }
if (showGrid && viewscale >= 8) renderGrid(state, viewport, viewscale); if (showGrid && viewscale >= 8) renderGrid(state, viewport, viewscale);

View File

@ -4,7 +4,7 @@
*/ */
import keycode from 'keycode'; import keycode from 'keycode';
import store from '../ui/store'; import store from './store';
import { import {
toggleGrid, toggleGrid,
togglePixelNotify, togglePixelNotify,

View File

@ -101,4 +101,3 @@ export function renderGrid(
viewportCtx.globalAlpha = 1; viewportCtx.globalAlpha = 1;
} }

View File

@ -45,7 +45,7 @@ function isCloudflareIp(testIpString: string): boolean {
if (!testIpString) return false; if (!testIpString) return false;
const testIp = intoAddress(testIpString); const testIp = intoAddress(testIpString);
if (!testIp) return false; if (!testIp) return false;
return cloudflareIps.some(cf => testIp.isInSubnet(cf)); return cloudflareIps.some((cf) => testIp.isInSubnet(cf));
} }
export default isCloudflareIp; export default isCloudflareIp;

View File

@ -30,7 +30,7 @@ export async function getIPFromRequest(req): ?string {
} }
const forwardedFor = headers['x-forwarded-for']; const forwardedFor = headers['x-forwarded-for'];
const ipList = forwardedFor.split(',').map(str => str.trim()); const ipList = forwardedFor.split(',').map((str) => str.trim());
let ip = ipList.pop(); let ip = ipList.pop();
while (isTrustedProxy(ip) && ipList.length) { while (isTrustedProxy(ip) && ipList.length) {

View File

@ -10,7 +10,7 @@ export function validateEMail(email) {
if (email.length < 5) return 'Email should be at least 5 characters long.'; if (email.length < 5) return 'Email should be at least 5 characters long.';
if (email.length > 40) return "Email can't be longer than 40 characters."; if (email.length > 40) return "Email can't be longer than 40 characters.";
if (email.indexOf('.') === -1) return 'Email should at least contain a dot'; if (email.indexOf('.') === -1) return 'Email should at least contain a dot';
if (email.split('').filter(x => x === '@').length !== 1) { if (email.split('').filter((x) => x === '@').length !== 1) {
return 'Email should contain a @'; return 'Email should contain a @';
} }
if (!mailTester.test(email)) return 'Your Email looks shady'; if (!mailTester.test(email)) return 'Your Email looks shady';
@ -21,12 +21,12 @@ export function validateName(name) {
if (!name) return "Name can't be empty."; if (!name) return "Name can't be empty.";
if (name.length < 4) return 'Name must be at least 4 characters long'; if (name.length < 4) return 'Name must be at least 4 characters long';
if (name.length > 26) return 'Name must be shorter than 26 characters'; if (name.length > 26) return 'Name must be shorter than 26 characters';
if (name.indexOf('@') !== -1 || if (name.indexOf('@') !== -1
name.indexOf('/') !== -1 || || name.indexOf('/') !== -1
name.indexOf('\\') !== -1 || || name.indexOf('\\') !== -1
name.indexOf('>') !== -1 || || name.indexOf('>') !== -1
name.indexOf('<') !== -1 || || name.indexOf('<') !== -1
name.indexOf('#') !== -1) { || name.indexOf('#') !== -1) {
return 'Name contains invalid character like @, /, \\ or #'; return 'Name contains invalid character like @, /, \\ or #';
} }
return false; return false;

View File

@ -62,13 +62,15 @@ app.use('/tiles', tiles);
/* level from -1 (default, 6) to 0 (no) from 1 (fastest) to 9 (best) /* level from -1 (default, 6) to 0 (no) from 1 (fastest) to 9 (best)
* Set custon filter to make sure that .bmp files get compressed * Set custon filter to make sure that .bmp files get compressed
*/ */
app.use(compression({ level: 3, app.use(compression({
level: 3,
filter: (req, res) => { filter: (req, res) => {
if (res.getHeader('Content-Type') === 'application/octet-stream') { if (res.getHeader('Content-Type') === 'application/octet-stream') {
return true; return true;
} }
return compression.filter(req, res); return compression.filter(req, res);
} })); },
}));
// //
@ -161,7 +163,7 @@ app.get('/', async (req, res) => {
// //
// ip config // ip config
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
const promise = models.sync().catch(err => logger.error(err.stack)); const promise = models.sync().catch((err) => logger.error(err.stack));
promise.then(() => { promise.then(() => {
server.listen(PORT, () => { server.listen(PORT, () => {
const address = server.address(); const address = server.address();