diff --git a/Makefile b/Makefile index 5662624..64f50bf 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ farm: make src/server/farm runprod: - cd dist/ && chmod +x farm && ./farm + cd dist/ && chmod +x farm && ./farm -:a50 upload: rsync -rtvz dist/ $(SERVER):~/farm diff --git a/assets/game/acf/game.scm b/assets/game/acf/game.scm index b5f3a51..9c3e992 100644 --- a/assets/game/acf/game.scm +++ b/assets/game/acf/game.scm @@ -47,7 +47,7 @@ "20 Cows on Peridier Ridge")))) (define *ff-text* - '(((p (img (@ (src "53c3a93b0867eee67b9b9f6ebc4c1f4a.gif") (style "float: left;"))) "Natural Disaster--The Solar Winds break through the atmosphere. You are luckily shielded by Mt Proctor. Your hay survives and jumps in price. " (b "COLLECT $500 per Hay acre") ". To see if they escaped, other players must roll. Odd: escaped, Even: hit. " (b "Wind hit players must clean up all acres at $100 per acre."))) + '(((p (img (@ (src "./assets/img/volcano2.53c3a93b0867eee67b9b9f6ebc4c1f4a.gif") (style "float: left;"))) "Natural Disaster--The Solar Winds break through the atmosphere. You are luckily shielded by Mt Proctor. Your hay survives and jumps in price. " (b "COLLECT $500 per Hay acre") ". To see if they escaped, other players must roll. Odd: escaped, Even: hit. " (b "Wind hit players must clean up all acres at $100 per acre."))) ((p "Planetary Disaster Fund comes through." (p (b "COLLECT $100 per Grain acre.")))) ((p "Another high wind spring and your wheat didn't get sprayed. Weeds take over and cut your harvest in half. Hold this card through Wheat Harvest for this year.")) ((p "Kept back some of your cows and Proxima B steak goes viral.") (p (b "COLLECT $2,000 if you have cows."))) diff --git a/package-lock.json b/package-lock.json index de9aa6f..fde7de8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2212,8 +2212,7 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" }, "array-unique": { "version": "0.3.2", @@ -2667,8 +2666,7 @@ "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, "bignumber.js": { "version": "2.4.0", @@ -3787,6 +3785,16 @@ "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", "dev": true }, + "css-url-relative-plugin": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-url-relative-plugin/-/css-url-relative-plugin-1.0.0.tgz", + "integrity": "sha1-T4FVU2I2Tw8ZG9HFKLwnsKdqFGw=", + "requires": { + "loader-utils": "^1.1.0", + "parse-import": "^2.0.0", + "webpack-sources": "^1.1.0" + } + }, "css-what": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", @@ -4189,8 +4197,7 @@ "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" }, "end-of-stream": { "version": "1.4.4", @@ -5486,6 +5493,15 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-imports": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-imports/-/get-imports-1.0.0.tgz", + "integrity": "sha1-R8C07piTUWQsVJdxk79Pyqv1N48=", + "requires": { + "array-uniq": "^1.0.1", + "import-regex": "^1.1.0" + } + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -6018,6 +6034,11 @@ "resolve-cwd": "^2.0.0" } }, + "import-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/import-regex/-/import-regex-1.1.0.tgz", + "integrity": "sha1-pVxS5McFx2XKIQ6SQqBrvMiqf2Y=" + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6500,7 +6521,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, "requires": { "minimist": "^1.2.0" } @@ -6619,7 +6639,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, "requires": { "big.js": "^5.2.2", "emojis-list": "^2.0.0", @@ -6918,8 +6937,7 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "minipass": { "version": "3.1.1", @@ -7681,6 +7699,14 @@ "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==", "dev": true }, + "parse-import": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-import/-/parse-import-2.0.0.tgz", + "integrity": "sha1-KyR0Aw4AirmNt2xLy/TbWucwb18=", + "requires": { + "get-imports": "^1.0.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -9694,8 +9720,7 @@ "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" }, "source-map": { "version": "0.5.7", @@ -10797,7 +10822,6 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, "requires": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" @@ -10806,8 +10830,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, diff --git a/package.json b/package.json index d5bd698..34b69ea 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@fortawesome/free-solid-svg-icons": "^5.12.0", "@fortawesome/react-fontawesome": "^0.1.8", "cookies-js": "^1.2.3", + "css-url-relative-plugin": "^1.0.0", "mobx": "^5.15.3", "mobx-react": "^6.1.4", "react": "^16.12.0", diff --git a/src/components/farm/Board.jsx b/src/components/farm/Board.jsx index 5fea180..87d1f61 100644 --- a/src/components/farm/Board.jsx +++ b/src/components/farm/Board.jsx @@ -348,6 +348,7 @@ class PlayerSummary extends React.Component { @@ -426,7 +427,9 @@ class PlayerTurnContainer extends React.Component {
) : (<>)} - {view} +
+ {view} +
@@ -1885,7 +1888,7 @@ class Info extends React.Component { const SCREENS = { summary: 'summary', misc: 'misc', farms: 'farms', cards: 'cards', trade: 'trade', loans: 'loans', - action: 'action', info: 'info' }; + action: 'action', info: 'info', error: 'error' }; class BoardApp extends React.Component { iconToScreen = { user: SCREENS.summary, 'window-restore': SCREENS.cards, @@ -1948,6 +1951,10 @@ class BoardApp extends React.Component { .find(p => p.player.name === this.props.game.currentPlayer).player; this.setState({ currentPlayer }); } + + if (!prevProps.ui.exn && this.props.ui.exn) { + this.setState({ screen: SCREENS.error }); + } } componentDidMount() { @@ -2170,6 +2177,7 @@ class BoardApp extends React.Component {
@@ -2212,6 +2220,11 @@ class BoardApp extends React.Component {
+
+

Error

+

A server error occured.

+

Reload game

+
diff --git a/src/components/farm/actionTypes.js b/src/components/farm/actionTypes.js index 77d31af..b0a8f4c 100644 --- a/src/components/farm/actionTypes.js +++ b/src/components/farm/actionTypes.js @@ -39,3 +39,4 @@ export const AUTO_SKIP = 'auto-skip' export const MESSAGE = 'message' export const SET_HARVEST_TABLE = 'set-harvest-table' export const SET_MOVING_SKIP = 'set-moving-skip' +export const SERVER_ERROR = 'server-error' diff --git a/src/components/farm/actions.js b/src/components/farm/actions.js index 43a241e..bde1b0e 100644 --- a/src/components/farm/actions.js +++ b/src/components/farm/actions.js @@ -21,13 +21,14 @@ import { UPDATE_GAME, UPDATE_PLAYER, GAME_STATE, SET_SELECTED_CARD, SET_CARDS, MP_MOUSE, SET_MP_DIMS, MARK_ACTION_CHANGE_HANDLED, SET_NEXT_ACTION, MOVE_PLAYER, NEXT_UI_ACTION, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED, AUTO_SKIP, MESSAGE, SET_HARVEST_TABLE, SET_CARD_ERROR, - SET_MOVING_SKIP } from './actionTypes.js' + SET_MOVING_SKIP, SERVER_ERROR } from './actionTypes.js' export { updateGame, updatePlayer, gameState, setSelectedCard, setCards, spacePushPlayer, spaceClearPlayers, setOldMessages, setMessagePanelSpace, mpMouse, setMPDims, movePlayer, setNextAction, nextUIAction, markActionChangeHandled, nextUIActionSilent, alert, alertHandled, - autoSkip, message, setHarvestTable, setCardError, setMovingSkip } + autoSkip, message, setHarvestTable, setCardError, setMovingSkip, + serverError } function updateGame(update) { return { type: UPDATE_GAME, @@ -135,3 +136,7 @@ function setHarvestTable(table) { function setMovingSkip(skip) { return { type: SET_MOVING_SKIP, skip }; } + +function serverError(exn) { + return { type: SERVER_ERROR, exn }; +} diff --git a/src/components/farm/interface.js b/src/components/farm/interface.js index 65d5792..635b106 100644 --- a/src/components/farm/interface.js +++ b/src/components/farm/interface.js @@ -25,7 +25,7 @@ import { updateGame, updatePlayer, gameState, setSelectedCard, setCards, movePlayer, setOldMessages, markActionChangeHandled, mpMouse, rolled, setNextAction, nextUIAction, nextUIActionSilent, alert, autoSkip, message, alertHandled, setHarvestTable, - setCardError, setMovingSkip } from './actions.js' + setCardError, setMovingSkip, serverError } from './actions.js' import { itemCard, fateCard } from 'game.js' export { initialize, buy, roll, endTurn, loan, trade, submitTradeAccept, @@ -42,6 +42,7 @@ function handleMessage(evt) { if (data.event === 'error') { console.log('error:' + data.exn); + store.dispatch(serverError(data.exn)); return; } batch(() => { diff --git a/src/components/farm/reducers.js b/src/components/farm/reducers.js index 4988994..865130b 100644 --- a/src/components/farm/reducers.js +++ b/src/components/farm/reducers.js @@ -22,7 +22,7 @@ import { UPDATE_GAME, UPDATE_PLAYER, GAME_STATE, SET_SELECTED_CARD, SET_CARDS, SET_MP_DIMS, MOVE_PLAYER, SET_NEXT_ACTION, NEXT_UI_ACTION, MARK_ACTION_CHANGE_HANDLED, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED, AUTO_SKIP, MESSAGE, SET_HARVEST_TABLE, SET_CARD_ERROR, - SET_MOVING_SKIP } from './actionTypes.js' + SET_MOVING_SKIP, SERVER_ERROR } from './actionTypes.js' import { GAME_STATES } from '../../constants.js' import { spaceContent, corners } from 'game.js' @@ -124,7 +124,8 @@ const initialState = { autoSkip: false, playerSpaces: {}, movingSkip: false, - harvestTable: false }, + harvestTable: false, + exn: false }, spaces: spaces, space: null, // message panel dimenions @@ -228,6 +229,8 @@ export default function(state = initialState, action) { return { ...state, ui: { ...state.ui, harvestTable: action.table }}; case SET_MOVING_SKIP: return { ...state, ui: { ...state.ui, movingSkip: action.skip }}; + case SERVER_ERROR: + return { ...state, ui: { ...state.ui, exn: action.exn }}; default: return state; } diff --git a/src/components/new-game/NewGame.jsx b/src/components/new-game/NewGame.jsx index 5bf4f5c..73b1ba7 100644 --- a/src/components/new-game/NewGame.jsx +++ b/src/components/new-game/NewGame.jsx @@ -25,6 +25,8 @@ import LoginOrCreateAccount from '../login-or-create-account/LoginOrCreateAccoun import { startOrJoinGame } from '../start/actions.js' import { start } from '../app/actions.js' +import { itemCardShort } from 'game.js' + import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faArrowCircleLeft, faCog } from '@fortawesome/free-solid-svg-icons' @@ -63,6 +65,7 @@ class NewGame extends React.Component { auditThreshold: 250000, startingCash: 5000, startingDebt: 5000, + startingOtbs: 2, trade: true, showLogin: false }; @@ -71,10 +74,10 @@ class NewGame extends React.Component { handleInputChange = e => { const target = e.target, value = target.type === 'checkbox' && target.name !== 'trade' - ? target.name : target.value, + ? target.name : target.value, name = target.type === 'checkbox' && target.name !== 'trade' - ? 'checkedColor' : target.name; + ? 'checkedColor' : target.name; this.setState({ [name]: value @@ -98,122 +101,129 @@ class NewGame extends React.Component { render() { let titleBar = !this.props.hideBack ? ( - - + + - - {this.props.title} - - ) : this.props.title, + + {this.props.title} + + ) : this.props.title, colors = this.props.colors.map(c => ( ) - ), + ), gameName = this.props.showGameName && ( - - - + + + ), settingsClass = this.state.showSettings ? '' : 'hidden', mainScreenClass = !this.state.showSettings ? '' : 'hidden'; return ( - {this.props.user ? ( -
-
- - - - {colors} -

- -
- {gameName} -
-
- - - - - - - - - - - -
- - -
- - {this.props.showGameName ? ( - - - - ) : ()} -
- -
-
- ) : ( - <> - Sign in or create account to continue - - - )} + {this.props.user ? ( +
+
+ + + + {colors} +

+ +
+ {gameName} +
+
+ + + + + + + + + + + + +
+ + +
+ + {this.props.showGameName ? ( + + + + ) : ()} +
+ +
+
+ ) : ( + <> + Sign in or create account to continue + + + )}
); } diff --git a/src/main.jsx b/src/main.jsx index bdda299..e78352d 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -78,6 +78,7 @@ const unsubscribeNewOrJoinGame = store.subscribe(() => { }); let autostart = new URL(window.location.href).searchParams.get('autostart'); +let rejoin = new URL(window.location.href).searchParams.get('reload-game'); function handleMessage(evt) { const data = JSON.parse(evt.data), @@ -86,6 +87,8 @@ function handleMessage(evt) { if (data.event === 'error') { console.log('error:' + data.exn); } else if (data.event === 'new-game-started') { + history.replaceState({}, document.title, '/'); + console.log('clearing auto-reload'); initialize(store, Ws.sendCommand); Ws.setMainOnMessage(handleMessageFarm); Ws.openSecondary('push-web-socket'); @@ -111,6 +114,10 @@ function handleMessage(evt) { gameName: data.games.games[0].name })); } } + if (rejoin) { + store.dispatch(startOrJoinGame({ type: 'join-as-existing', + gameId: false })); + } } } diff --git a/src/server/farm.scm b/src/server/farm.scm index f724e30..ead947c 100644 --- a/src/server/farm.scm +++ b/src/server/farm.scm @@ -18,7 +18,7 @@ ;;; . (import chicken scheme srfi-1 data-structures) -(use http-session srfi-69 coops uri-common +(use http-session srfi-69 coops coops-utils uri-common srfi-18 medea numbers spiffy spiffy-cookies intarweb pll sxml-transforms websockets miscmacros mailbox) @@ -156,7 +156,8 @@ (audit-threshold . 250000) (starting-cash . 5000) (starting-debt . 5000) - (trade . #t)) + (trade . #t) + (starting-otbs . 2)) accessor: game-settings) (mutex initform: (make-mutex 'game) accessor: game-mutex))) @@ -169,8 +170,8 @@ (mutex initform: (make-mutex 'app) accessor: app-mutex))) (define (player->sexp player) - `((cash . ,(player-cash player)) - (debt . ,(player-debt player)) + `((cash . ,(inexact->exact (round (player-cash player)))) + (debt . ,(inexact->exact (round (player-debt player)))) (space . ,(player-space player)) (previous-space . ,(player-previous-space player)) (state . ,(player-state player)) @@ -247,12 +248,54 @@ 'games (map sexp->game (alist-ref 'games x)) 'last-game-id (alist-ref 'last-game-id x))) -(define (save-app) - (with-output-to-file "/home/tjhintz/app.scm" - (lambda () - (write (app->sexp *app*))))) +(define (validate-game g) + (assert (instance-of? g )) + (assert (number? (game-id g))) + (assert (list? (game-players g))) + (for-each (lambda (p) + (assert (instance-of? p )) + (assert (number? (player-cash p))) + (assert (number? (player-display-cash p))) + (assert (= (player-cash p) (player-display-cash p))) + (assert (number? (player-debt p))) + (assert (number? (player-space p))) + (assert (number? (player-previous-space p))) + (assert (symbol? (player-state p))) + (assert (member (player-state p) '(turn-ended pre-turn mid-turn))) + (assert (boolean? (player-finished p))) + (assert (list? (player-assets p))) ;; TODO test assets + (assert (list? (player-ridges p))) + (assert (number? (player-harvest-mult p))) + (assert (list? (player-otbs p))) + (assert (list? (player-farmers-fates p))) + (assert (list? (player-year-rules p))) + (assert (list? (player-next-year-rules p))) + (assert (symbol? (player-color p))) + (assert (string? (player-name p))) + (assert (number? (player-user-id p))) + (assert (list? (player-trade p))) + (assert (number? (player-last-cash p))) + (assert (boolean? (player-harvesting p))) + (assert (boolean? (player-hay-doubled p))) + (assert (boolean? (player-corn-doubled p)))) + (game-players g)) + (assert (list? (game-otbs g))) + (assert (list? (game-used-otbs g))) + (assert (list? (game-farmers-fates g))) + (assert (list? (game-operating-expenses g))) + (assert (number? (game-operating-expense-index g))) + (assert (list? (game-colors g))) + (assert (or (instance-of? (game-called-audit g) ) + (boolean? (game-called-audit g)))) + (assert (symbol? (game-state g))) ;; TODO test all symbols + (assert (string? (game-name g))) + (assert (number? (game-turn g))) + (assert (or (instance-of? (game-current-player g) ) + (boolean? (game-current-player g)))) + (assert (list? (game-settings g)))) (define (save-game game) + (validate-game game) (db-update-game (game-id game) (symbol->string (game-state game)) (game->sexp game))) @@ -293,7 +336,9 @@ (set-cookie! (session-cookie-name) sid)))) (session-lifetime (* 60 60 24 7 4)) -(access-log (current-output-port)) +;; (access-log (current-output-port)) +(access-log "access.log") +(error-log "error.log") (handle-not-found (let ((old-handler (handle-not-found))) @@ -577,14 +622,21 @@ (lambda (p1 p2) (> (player-net-worth p1) (player-net-worth p2)))))) - (bonus (max (farming-round - (* (- (player-net-worth richest) - (player-net-worth player)) - 0.2)) - 2500))) + ;; (bonus (max (farming-round + ;; (inexact->exact + ;; (round + ;; (* (- (player-net-worth richest) + ;; (+ (player-net-worth player) + ;; ;; don't give a bonus for emergency debt + ;; (max 0 (- (player-debt player) (game-setting 'max-debt game))))) + ;; 0.2)))) + ;; 2500)) + (bonus 5000) + ) (safe-set! (player-cash player) - ;; (+ (player-cash player) 5000) - (+ (player-cash player) bonus)) + (+ (player-cash player) 5000) + ;; (+ (player-cash player) bonus) + ) (safe-set! (player-display-cash player) (player-cash player)) (safe-set! (game-actions game) (cons `((?action . info) @@ -827,8 +879,8 @@ #f))) (define (call-audit game player) - (if (game-called-audit game) - (begin (safe-set! (game-called-audit game) player)))) + (if (not (game-called-audit game)) + (safe-set! (game-called-audit game) player))) (define (player-net-worth player) (+ (* (+ (player-asset 'hay player) (player-asset 'grain player)) 2000) @@ -942,6 +994,17 @@ rolls)) (_make-rolls n 1 (list (next-roll -1)))) +(define (log-error exn) + (with-output-to-file (error-log) + (lambda () + (print-call-chain) + (print exn) + (print-error-message exn)) + append:)) + +(define (log-msg msg) + (log-to (error-log) "~A" msg)) + (define (process-message player game type msg) (when player (safe-set! (player-last-cash player) (player-cash player))) @@ -1253,10 +1316,8 @@ (begin (advance-turn game player) (handle-exceptions exn - (begin (print-call-chain) - (print exn) - (print-error-message exn) - (print "error saving app")) + (begin (log-error exn) + (log-msg "error saving app")) (save-game game)) (if (eq? (game-state game) 'finished) (do-end-of-game game) @@ -1286,6 +1347,10 @@ 0)) (starting-debt . ,(->i (alist-ref 'startingDebt msg) 0)) + (starting-otbs . ,(min (max (->number (alist-ref 'startingOtbs msg) + 2) + 0) + 8)) (trade . ,(or (alist-ref 'trade msg) #t))))) (player (add-player-to-game game color @@ -1301,7 +1366,7 @@ (session-set! (sid) 'game-id (game-id game))) (*game* game) (*player* player) - (set-startup-otbs game player 2) + (set-startup-otbs game player (alist-ref 'starting-otbs (game-settings game))) ;; (set-startup-otbs game ai-player 2) ;; (thread-start! (make-ai-push-receiver game ai-player)) (create-start-response "new-game-started"))) @@ -1323,11 +1388,12 @@ (db-add-user-game (alist-ref 'id user) (game-id game)) (*game* game) (*player* player) - (set-startup-otbs game player 2) + (set-startup-otbs game player (alist-ref 'starting-otbs (game-settings game))) (message-players! game player '() type: "update") (create-start-response "new-game-started"))) ((string=? type "join-as-existing") - (let* ((id (alist-ref 'gameId msg)) + (let* ((id (or (alist-ref 'gameId msg) + (session-ref (sid) 'game-id))) (user-id (session-ref (sid) 'user-id)) (game (find-game id)) (player (find (lambda (p) (equal? (player-user-id p) user-id)) @@ -1440,19 +1506,19 @@ exn (send-message (json->string - `((exn . ,(with-output-to-string - (lambda () - (print-call-chain) - (print-error-message exn)))) + `((exn . ,(begin (log-error exn) + (conc "Server error: " (with-output-to-string + (lambda () + (print-error-message exn)))))) (event . "error")))) (send-message (json->string (handle-exceptions exn - `((exn . ,(with-output-to-string - (lambda () - (print-call-chain) - (print-error-message exn)))) + `((exn . ,(begin (log-error exn) + (conc "Server error: " (with-output-to-string + (lambda () + (print-error-message exn)))))) (event . "error")) (session-game) (let* ((game (*game*)) @@ -1492,18 +1558,18 @@ exn (send-message (json->string - `((exn . ,(with-output-to-string - (lambda () - (print-call-chain) - (print-error-message exn))))))) + `((exn . ,(begin (log-error exn) + (conc "Server error: " (with-output-to-string + (lambda () + (print-error-message exn))))))))) (send-message (json->string (handle-exceptions exn - `((exn . ,(with-output-to-string - (lambda () - (print-call-chain) - (print-error-message exn)))) + `((exn . ,(begin (log-error exn) + (conc "Server error: " (with-output-to-string + (lambda () + (print-error-message exn)))))) (event . "error")) (create-ws-response (*player*) (alist-ref 'type msg) @@ -2143,7 +2209,10 @@ (let ((value (alist-ref '?value action))) (if (procedure? value) (value player) - (apply (alist-ref (car value) *action-map*) player (cdr value))))) + (let ((action-proc (alist-ref (car value) *action-map*))) + (if (procedure? action-proc) + (apply action-proc player (cdr value)) + (print (conc "unknown action value: " value))))))) ((eq? a 'harvest-mult) (safe-set! (player-harvest-mult player) (* (player-harvest-mult player) (alist-ref '?value action)))) @@ -2314,3 +2383,207 @@ ;; Error: (assv) bad argument type: #'> ;; when getting trade the name is wrong + +;; error: +;; Call history: + +;; farm.scm:482: player-last-cash +;; farm.scm:99: coops#slot-value +;; farm.scm:483: player-hay-doubled +;; farm.scm:99: coops#slot-value +;; farm.scm:484: player-corn-doubled +;; farm.scm:99: coops#slot-value +;; farm.scm:513: list->vector +;; farm.scm:517: game-called-audit +;; farm.scm:135: coops#slot-value +;; farm.scm:518: game-called-audit +;; farm.scm:135: coops#slot-value +;; farm.scm:518: player-name +;; farm.scm:1450: k8469 +;; farm.scm:1450: g8473 +;; farm.scm:1452: with-output-to-string +;; farm.scm:1454: print-call-chain <-- + +;; Error: (player-name) no method defined for given argument classes: (#t) + +;; clicking roll button + + + +;; start game with more otbs + + +;; Error: (assv) bad argument type: #f + +;; Call history: + +;; numbers.scm:1672: scan-real +;; numbers.scm:1671: scan-ureal +;; numbers.scm:1603: scan-digits+hashes +;; numbers.scm:1549: scan-digits +;; numbers.scm:1531: lp +;; numbers.scm:1531: lp +;; numbers.scm:1548: g1937 +;; numbers.scm:1720: %string->compnum +;; numbers.scm:1672: scan-real +;; numbers.scm:1671: scan-ureal +;; numbers.scm:1603: scan-digits+hashes +;; numbers.scm:1549: scan-digits +;; numbers.scm:1531: lp +;; numbers.scm:1548: g1937 +;; farm.scm:50: expiration +;; farm.scm:43: current-milliseconds +;; farm.scm:44: http-session#session-lifetime +;; farm.scm:44: numbers#* +;; numbers.scm:382: %* +;; farm.scm:44: numbers#floor +;; farm.scm:44: numbers#inexact->exact +;; numbers.scm:867: exact? +;; farm.scm:43: numbers#+ +;; numbers.scm:295: %+ +;; farm.scm:50: spiffy#remote-address +;; farm.scm:50: http-session#make-session-item +;; farm.scm:1441: *game* +;; farm.scm:1449: *game* +;; farm.scm:1476: *game* +;; farm.scm:1477: *player* +;; farm.scm:1479: alist-ref +;; farm.scm:1468: k8474 +;; farm.scm:1468: g8478 +;; farm.scm:1470: log-error +;; farm.scm:954: spiffy#error-log +;; farm.scm:954: with-output-to-file +;; farm.scm:956: print-call-chain +;; farm.scm:957: print +;; farm.scm:958: print-error-message +;; farm.scm:1471: with-output-to-string +;; farm.scm:1473: print-error-message +;; farm.scm:1471: conc +;; farm.scm:1467: medea#json->string +;; farm.scm:1466: websockets#send-message +;; farm.scm:1455: k8462 +;; farm.scm:1455: g8466 +;; farm.scm:1461: log-error +;; farm.scm:954: spiffy#error-log +;; farm.scm:954: with-output-to-file +;; farm.scm:956: print-call-chain <-- +;; # + +;; Error: cannot write to socket - Broken pipe: 7 +;; [Sat Apr 11 23:04:48 2020] "GET http://localhost:8080/websocket/web-socket HTTP/1.1" Uncaught exception: +;; # + + + +;; Call history: + +;; farm.scm:164: game-settings +;; farm.scm:135: coops#slot-value +;; farm.scm:164: alist-ref +;; farm.scm:164: game-settings +;; farm.scm:135: coops#slot-value +;; farm.scm:164: alist-ref +;; farm.scm:164: game-settings +;; farm.scm:135: coops#slot-value +;; farm.scm:164: alist-ref +;; farm.scm:164: game-settings +;; farm.scm:135: coops#slot-value +;; farm.scm:164: alist-ref +;; farm.scm:164: game-settings +;; farm.scm:135: coops#slot-value +;; farm.scm:164: alist-ref +;; farm.scm:866: append +;; farm.scm:1483: game-last-updated +;; farm.scm:135: coops#slot-value +;; farm.scm:1483: numbers#+ +;; numbers.scm:295: %+ +;; farm.scm:1483: game-mutex +;; farm.scm:135: coops#slot-value +;; farm.scm:1483: dynamic-wind +;; farm.scm:1483: mutex-lock! +;; farm.scm:1483: ##sys#setter +;; farm.scm:1483: g8506 +;; farm.scm:135: coops#set-slot-value! +;; farm.scm:1483: mutex-unlock! +;; farm.scm:1484: *player* +;; farm.scm:1485: *player* +;; farm.scm:1485: game-last-updated +;; farm.scm:135: coops#slot-value +;; farm.scm:1485: player-mutex +;; farm.scm:99: coops#slot-value +;; farm.scm:1485: dynamic-wind +;; farm.scm:1485: mutex-lock! +;; farm.scm:1485: ##sys#setter +;; farm.scm:1485: g8526 +;; farm.scm:99: coops#set-slot-value! +;; farm.scm:1485: mutex-unlock! +;; tmp213217 +;; farm.scm:1469: k8475 +;; farm.scm:1469: g8479 +;; farm.scm:1468: medea#json->string +;; farm.scm:1456: k8463 +;; farm.scm:1456: g8467 +;; farm.scm:1462: log-error +;; farm.scm:955: spiffy#error-log +;; farm.scm:955: with-output-to-file +;; farm.scm:957: print-call-chain <-- +;; # + +;; Error: (symbol->string) bad argument type - not a symbol: (contents . "\n

LEASE Marineris Ridge

\n

for 30 years at $20,000

\n

... + + +;; rror: (assv) bad argument type: pre-turn + +;; Call history: + +;; sql-de-lite.scm:600: statement-ptr +;; sql-de-lite.scm:609: statement-ptr +;; sql-de-lite.scm:222: ##sys#block-set! +;; sql-de-lite.scm:612: remove-active-statement! +;; sql-de-lite.scm:202: hash-table-delete! +;; sql-de-lite.scm:893: for-each-active-statement +;; sql-de-lite.scm:204: hash-table-walk +;; sql-de-lite.scm:172: ##sys#block-set! +;; sql-de-lite.scm:897: object-release +;; sql-de-lite.scm:172: ##sys#block-set! +;; db.scm:28: alist-ref +;; db.scm:27: with-input-from-string +;; numbers.scm:1720: %string->compnum +;; numbers.scm:1672: scan-real +;; numbers.scm:1671: scan-ureal +;; numbers.scm:1603: scan-digits+hashes +;; numbers.scm:1549: scan-digits +;; numbers.scm:1531: lp +;; numbers.scm:1531: lp +;; numbers.scm:1548: g1937 +;; numbers.scm:1720: %string->compnum +;; numbers.scm:1672: scan-real +;; numbers.scm:1671: scan-ureal +;; numbers.scm:1603: scan-digits+hashes +;; numbers.scm:1549: scan-digits +;; numbers.scm:1531: lp +;; numbers.scm:1548: g1937 +;; farm.scm:50: expiration +;; farm.scm:43: current-milliseconds +;; farm.scm:44: http-session#session-lifetime +;; farm.scm:44: numbers#* +;; numbers.scm:382: %* +;; farm.scm:44: numbers#floor +;; farm.scm:44: numbers#inexact->exact +;; numbers.scm:867: exact? +;; farm.scm:43: numbers#+ +;; numbers.scm:295: %+ +;; farm.scm:50: spiffy#remote-address +;; farm.scm:50: http-session#make-session-item +;; farm.scm:1484: *game* +;; farm.scm:1492: *game* +;; farm.scm:1519: *game* +;; farm.scm:1520: *player* +;; farm.scm:1522: alist-ref +;; farm.scm:1511: k8652 +;; farm.scm:1511: g8656 +;; farm.scm:1513: log-error +;; farm.scm:997: spiffy#error-log +;; farm.scm:997: with-output-to-file +;; farm.scm:999: print-call-chain <-- +;; # diff --git a/webpack.common.js b/webpack.common.js index fa9c6c0..9aace77 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -24,15 +24,28 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CopyPlugin = require('copy-webpack-plugin'); const webpack = require("webpack"); const autoprefixer = require("autoprefixer"); +const CssUrlRelativePlugin = require('css-url-relative-plugin') module.exports = { entry: { app: './src/main.jsx', }, output: { - filename: '[name].bundle.js', + filename: './assets/[name].[contenthash].js', path: path.resolve(__dirname, 'dist'), }, + optimization: { + runtimeChunk: 'single', + splitChunks: { + cacheGroups: { + vendor: { + test: /[\\/]node_modules[\\/]/, + name: 'vendors', + chunks: 'all', + }, + }, + }, + }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ @@ -42,8 +55,8 @@ module.exports = { }), new FaviconsWebpackPlugin('./assets/img/tractor.svg'), new MiniCssExtractPlugin({ - filename: '[name].css', - chunkFilename: '[id].css', + filename: './assets/[name].[contenthash].css', + chunkFilename: './assets/[id].[contenthash].css', }), new CopyPlugin([ { from: './src/server/farm.scm', to: './[name].[ext]' }, @@ -57,6 +70,7 @@ module.exports = { ] } }), + new CssUrlRelativePlugin() ], module: { rules: [ @@ -71,11 +85,19 @@ module.exports = { } } }, + // { + // test: /mars-texture.png$/, + // loader: 'file-loader', + // options: { + // name: './assets/img/[name].[contenthash].[ext]', + // }, + // }, { test: /\.(woff|woff2|eot|ttf|otf|svg|png|gif)$/, - use: [ - 'file-loader', - ], + loader: 'file-loader', + options: { + name: './assets/img/[name].[contenthash].[ext]', + }, }, { test: /\.s[ac]ss$/i,