Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Master -> Dev #834

Merged
merged 29 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1838dfa
Fix king of the hill center star calculation and add 48p support
mike-eason Dec 1, 2023
2fe273e
Disable abandoning stars in standard games
mike-eason Dec 5, 2023
64ee6de
Fix territory drawing
mike-eason Dec 15, 2023
623d4bc
Upgrade mongo version to 5
mike-eason Dec 26, 2023
2dae6e4
Remove outdated google analytics
mike-eason Dec 26, 2023
b7aa8dc
Update SelectAlias.vue
Metritutus Nov 15, 2023
5a2e8d0
Fixed typo in irregular.ts
IHateAttackMaps Jan 8, 2024
3efc118
Fixed carrierSpeed units in GameSettings.vue
IHateAttackMaps Jan 8, 2024
20e06f0
Add buttons for pausing and resuming games
SpacialCircumstances Sep 27, 2023
a0ab590
Have one loading spinner for game details page
SpacialCircumstances Sep 27, 2023
4e229dd
Make requests to backend when pausing/resuming
SpacialCircumstances Sep 27, 2023
ecd4b47
Implement endpoint for game pause/resume
SpacialCircumstances Sep 28, 2023
f515da9
Implement game pausing
SpacialCircumstances Sep 28, 2023
981ca7d
Show resume button as warning
SpacialCircumstances Oct 1, 2023
850b6dc
Improve pausing logic
SpacialCircumstances Oct 1, 2023
e81c42e
Reset afk timers after unpausing game
SpacialCircumstances Dec 31, 2023
a3c3226
Cleanup
mike-eason Jan 9, 2024
743a2d7
Merge pull request #820 from solaris-games/feature/pause-games
mike-eason Jan 9, 2024
4ed5072
Merge pull request #827 from IHateAttackMaps/fix-unit
mike-eason Jan 9, 2024
88dead8
Merge pull request #826 from IHateAttackMaps/fix-typo
mike-eason Jan 9, 2024
f227b8a
Merge pull request #825 from Metritutus/spelling-correction
mike-eason Jan 9, 2024
c7a63ec
Fixed issue in extra dark games
IHateAttackMaps Jan 11, 2024
ea8918f
Fix the fix
IHateAttackMaps Jan 11, 2024
31f43a7
Merge pull request #828 from IHateAttackMaps/game-leaderboard-fix
mike-eason Jan 12, 2024
2b04cc2
Fix get conversation exploit
mike-eason Jan 12, 2024
6aeec0d
Fixed convo exploit part 2
mike-eason Jan 13, 2024
6ec6908
Fix impersonation of web sockets exploit
mike-eason Jan 14, 2024
1146246
Fix build errors
mike-eason Jan 14, 2024
d353cc7
Actually fixed message spoofing exploit
mike-eason Jan 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The client uses the following tech:
## Development Environment Setup
1. Install the prerequisites.
- [Node.js](https://nodejs.org/en/) v14
- [MongoDB](https://www.mongodb.com/) v4.4
- [MongoDB](https://www.mongodb.com/) v5.0
2. Clone the repository.
3. Checkout `master`.
4. `npm install` in both `client/` and `server/` directories.
Expand Down
1 change: 0 additions & 1 deletion client/.env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
VUE_APP_API_HOST=http://localhost:3000
VUE_APP_SOCKETS_HOST=localhost:3000
VUE_APP_GOOGLE_ANALYTICS_TRACKING_CODE=ABC-123-1
VUE_APP_DOCUMENTATION_URL=https://solaris-games.github.io/solaris-docs
VUE_APP_GOOGLE_RECAPTCHA_ENABLED=false
VUE_APP_GOOGLE_RECAPTCHA_SITE_KEY=ABC_123
Expand Down
11 changes: 0 additions & 11 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"voronoi": "^1.0.0",
"vue": "^2.6.12",
"vue-chartjs": "^3.5.1",
"vue-gtag": "^1.14.0",
"vue-recaptcha": "^1.3.0",
"vue-router": "^3.5.1",
"vue-socket.io": "^3.0.10",
Expand Down
28 changes: 15 additions & 13 deletions client/src/game/territories.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,22 +318,24 @@ class Territories {
// let sanitizedPoints = points
let sanitizedPoints = points.map(getPoint)

// Draw the graphic
let territoryGraphic = new PIXI.Graphics()
territoryGraphic.lineStyle(borderWidth, colour, 1)
territoryGraphic.beginFill(colour, 0.3)
territoryGraphic.moveTo(sanitizedPoints[0].x, sanitizedPoints[0].y)

for (let point of sanitizedPoints) {
territoryGraphic.lineTo(point.x, point.y)
}
if (sanitizedPoints.length) {
// Draw the graphic
let territoryGraphic = new PIXI.Graphics()
territoryGraphic.lineStyle(borderWidth, colour, 1)
territoryGraphic.beginFill(colour, 0.3)
territoryGraphic.moveTo(sanitizedPoints[0].x, sanitizedPoints[0].y)

for (let point of sanitizedPoints) {
territoryGraphic.lineTo(point.x, point.y)
}

// Draw another line back to the origin.
territoryGraphic.lineTo(sanitizedPoints[0].x, sanitizedPoints[0].y)
// Draw another line back to the origin.
territoryGraphic.lineTo(sanitizedPoints[0].x, sanitizedPoints[0].y)

territoryGraphic.endFill()
territoryGraphic.endFill()

this.container.addChild(territoryGraphic)
this.container.addChild(territoryGraphic)
}
}
// ----------

Expand Down
9 changes: 0 additions & 9 deletions client/src/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import Vue from 'vue'
import VueSocketio from 'vue-socket.io' // NOTE: There is an issue with >3.0.7 so forced to use 3.0.7, see here: https://stackoverflow.com/questions/61769716/vue-socket-connection-not-triggered
import VueGtag from 'vue-gtag'
import Toasted from 'vue-toasted'
import App from './App.vue'
import router from './router'
Expand Down Expand Up @@ -30,14 +29,6 @@ Vue.use(new VueSocketio({
}
}))

let trackingCode = process.env.VUE_APP_GOOGLE_ANALYTICS_TRACKING_CODE

if (trackingCode) {
Vue.use(VueGtag, {
config: { id: trackingCode }
}, router)
}

Vue.use(Toasted, {
position: 'bottom-right',
duration: 2500
Expand Down
14 changes: 14 additions & 0 deletions client/src/services/api/game.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@ class GameService extends BaseApiService {
{ withCredentials: true })
}

pause (gameId) {
return axios.put(this.BASE_URL + 'game/' + gameId + '/pause', {
pause: true
},
{ withCredentials: true })
}

resume (gameId) {
return axios.put(this.BASE_URL + 'game/' + gameId + '/pause', {
pause: false
},
{ withCredentials: true })
}

confirmReady (gameId) {
return axios.put(this.BASE_URL + 'game/' + gameId + '/ready', null,
{ withCredentials: true })
Expand Down
4 changes: 4 additions & 0 deletions client/src/services/gameHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,10 @@ class GameHelper {
return !game.state.startDate
}

isGameStarted (game) {
return game.state.startDate != null
}

isGameInProgress (game) {
return !this.isGameWaitingForPlayers(game) && !this.isGamePaused(game) && game.state.startDate != null && moment().utc().diff(game.state.startDate) >= 0 && !game.state.endDate
}
Expand Down
78 changes: 61 additions & 17 deletions client/src/views/game/Detail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<view-container>
<view-title title="Game Settings" navigation="main-menu"/>

<loading-spinner :loading="isLoadingGame"/>
<loading-spinner :loading="isLoading"/>

<div v-if="!isLoadingGame">
<div v-if="!isLoading">
<view-subtitle v-bind:title="game.settings.general.name" class="mt-2"/>

<p v-if="game.settings.general.description">{{game.settings.general.description}}</p>
Expand All @@ -18,6 +18,8 @@
</div>
<div class="col-auto">
<button class="btn btn-danger" v-if="!game.state.startDate && game.settings.general.isGameAdmin" @click="deleteGame">Delete Game</button>
<button class="btn btn-warning" v-if="canModifyPauseState() && !game.state.paused" @click="pauseGame">Pause Game</button>
<button class="btn btn-warning" v-if="canModifyPauseState() && game.state.paused" @click="resumeGame">Resume Game</button>
<router-link :to="{ path: '/game', query: { id: game._id } }" tag="button" class="btn btn-success ms-1">Open Game <i class="fas fa-arrow-right"></i></router-link>
</div>
</div>
Expand All @@ -39,7 +41,6 @@ import ViewTitle from '../components/ViewTitle'
import ViewSubtitle from '../components/ViewSubtitle'
import ViewContainer from '../components/ViewContainer'
import GameSettings from './components/settings/GameSettings'
import FluxBar from './components/menu/FluxBar'
import gameService from '../../services/api/game'
import router from '../../router'
import GameHelper from '../../services/gameHelper'
Expand All @@ -54,7 +55,7 @@ export default {
},
data () {
return {
isLoadingGame: true,
isLoading: true,
game: {
_id: null,
settings: {
Expand All @@ -70,34 +71,77 @@ export default {
this.game._id = this.$route.query.id
},
async mounted () {
this.isLoadingGame = true
await this.loadGame()
},
methods: {
canModifyPauseState () {
return this.game.settings.general.isGameAdmin
&& GameHelper.isGameStarted(this.game)
&& !GameHelper.isGamePendingStart(this.game)
&& !GameHelper.isGameFinished(this.game);
},
async loadGame () {
this.isLoading = true

try {
let response = await gameService.getGameInfo(this.game._id)
try {
let response = await gameService.getGameInfo(this.game._id)

this.game = response.data
} catch (err) {
console.error(err)
}
this.game = response.data
} catch (err) {
console.error(err)
}

this.isLoadingGame = false
},
methods: {
this.isLoading = false
},
async pauseGame () {
if (await this.$confirm('Pause game', 'Are you sure you want to pause this game?')) {
this.isLoading = true

try {
await gameService.pause(this.game._id)

this.$toasted.show(`The game has been paused. Please notify the players.`, { type: 'success' })

await this.loadGame()
} catch (err) {
console.error(err)
}

this.isLoading = false
}
},
async resumeGame () {
if (await this.$confirm('Resume game', 'Are you sure you want to resume this game?')) {
this.isLoading = true

try {
await gameService.resume(this.game._id)

this.$toasted.show(`The game has been resumed. Please notify the players.`, { type: 'success' })

await this.loadGame()
} catch (err) {
console.error(err)
}

this.isLoading = false
}
},
async deleteGame () {
if (await this.$confirm('Delete game', 'Are you sure you want to delete this game?')) {
this.isDeletingGame = true
this.isLoading = true

try {
let response = await gameService.delete(this.game._id)

if (response.status === 200) {
router.push({ name: 'main-menu' })
router.push({name: 'main-menu'})
}
} catch (err) {
console.error(err)
}

this.isDeletingGame = false
this.isLoading = false
}
}
},
Expand Down
6 changes: 2 additions & 4 deletions client/src/views/game/Game.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ export default {
let player = GameHelper.getUserPlayer(this.$store.state.game)

let socketData = {
gameId: this.$store.state.game._id,
userId: this.$store.state.userId
gameId: this.$store.state.game._id
}

if (player) {
Expand Down Expand Up @@ -111,8 +110,7 @@ export default {
this.unsubscribeToSockets()

let socketData = {
gameId: this.$store.state.game._id,
userId: this.$store.state.userId
gameId: this.$store.state.game._id
}

let player = GameHelper.getUserPlayer(this.$store.state.game)
Expand Down
2 changes: 1 addition & 1 deletion client/src/views/game/components/settings/GameSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
v-if="game.settings.galaxy.galaxyType !== 'custom'"/>
<game-setting-value title="Carrier Speed"
tooltip="Carriers go brrr"
:valueText="(game.settings.specialGalaxy.carrierSpeed / game.constants.distances.lightYear)+'/ly tick'"
:valueText="(game.settings.specialGalaxy.carrierSpeed / game.constants.distances.lightYear)+' ly/tick'"
:value="game.settings.specialGalaxy.carrierSpeed"
:compareValue="compareSettings.specialGalaxy.carrierSpeed"/>
<game-setting-value title="Star Capture Rewards"
Expand Down
2 changes: 1 addition & 1 deletion client/src/views/game/components/welcome/SelectAlias.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<select-avatar v-on:onAvatarChanged="onAvatarChanged"/>
</div>
<div class="col pt-0">
<p v-if="!avatar">Every great story needs both heroes and villians. Which will you be?</p>
<p v-if="!avatar">Every great story needs both heroes and villains. Which will you be?</p>

<h5 v-if="avatar">{{avatar.name}}</h5>
<p v-if="avatar"><small class="linebreaks">{{avatar.description}}</small></p>
Expand Down
18 changes: 18 additions & 0 deletions server/api/controllers/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,24 @@ export default (container: DependencyContainer) => {
return next(err);
}
},
togglePaused: async (req, res, next) => {
try {
const doPause = req.body?.pause;

if (doPause === null || doPause === undefined) {
throw new ValidationError('Pause parameter is required.');
}

await container.gameService.setPauseState(
req.game,
doPause,
req.session.userId);

return res.sendStatus(200);
} catch (err) {
return next(err);
}
},
getPlayerUser: async (req, res, next) => {
try {
let user = await container.gameService.getPlayerUser(
Expand Down
11 changes: 7 additions & 4 deletions server/api/express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ export default async (config: Config, app, container: DependencyContainer) => {

// ---------------
// Set up MongoDB session store
let store = new MongoDBStore({
let sessionStorage = new MongoDBStore({
uri: config.connectionString,
collection: 'sessions'
});

// Catch session store errors
store.on('error', function(err) {
sessionStorage.on('error', function(err) {
console.error(err);
});

Expand All @@ -37,7 +37,7 @@ export default async (config: Config, app, container: DependencyContainer) => {
secure: config.sessionSecureCookies, // Requires HTTPS
maxAge: 1000 * 60 * 60 * 24 * 365 // 1 Year
},
store
store: sessionStorage
}));

// ---------------
Expand Down Expand Up @@ -86,5 +86,8 @@ export default async (config: Config, app, container: DependencyContainer) => {

console.log('Express intialized.');

return app;
return {
app,
sessionStorage
};
};
8 changes: 5 additions & 3 deletions server/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ async function startServer() {
const app = express();
const server = http.createServer(app);

const io = socketLoader(server);
const container = containerLoader(config, io);
const container = containerLoader(config);

await expressLoader(config, app, container);
const { sessionStorage } = await expressLoader(config, app, container);

const io = socketLoader(config, server, sessionStorage);
container.broadcastService.setIOController(io);

server.listen(config.port, (err) => {
if (err) {
Expand Down
Loading
Loading