-
-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Updated vue, socket.io, socket.io-client and cookie-parser NPM pack…
…ages. * Installed @types/cookie-parser NPM package. * Overhauled socket and eventBus functionality to add type safety, consolidate socket event handling, and fix issues relating to event subscription/unsubscription (ie those times when the highlight for the event/chat buttons wouldn't update when they should), as well as adding connection resiliency. * Updated readyToQuit() and unreadyToQuit() endpoints in GameController to not broadcast gamePlayerReadyToQuit or gamePlayerNotReadyToQuit events, respectively, if the readyToQuitVisibility setting is set to 'hidden'. If broadcasting the event, if the readyToQuitVisibility setting is NOT set to visible, the player Id is not included in the response data. * Updated LedgerRow component: - Added functionality to prevent a player from trying to settle a debt if they have none of the relevant funds (credits/specialist tokens). - Fixed settleDebt() method not updating the user player's credit/specialist token amounts when settling a debt. - Updated settleDebt() method to improve toast message so that it reflects whether or not the player was only able to pay off some of the debt. * Renamed main.js to main.ts to add Typescript support. * Updated store.ts to use constants for some mutation names. * Updated GamePlayerReadyToQuit and GamePlayerNotReadyToQuit mutations in store.ts to account for the playerId not being supplied, and to update the readyToQuitCount. * Renamed sockets.ts to socket.js and updated to be SocketService. - Updated getUserId() method to fix circumstances where the returned Promise would not get resolved. - Moved gameRoomjoined and gameRoomLeft socket event handling functionality to PlayerServerSocketEventHandler. * Moved roomExists(), playerRoomExists() and getOnlinePlayers() methods out of BroadcastService and into new SocketService. * Moved LedgerType enum from server to common.
- Loading branch information
1 parent
93fc956
commit 21544ec
Showing
69 changed files
with
2,089 additions
and
871 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import mitt, { type EventType, type Handler } from 'mitt'; | ||
import type { EventBus } from './eventBus'; | ||
import { type EventBusEventName } from './eventBusEventNames/eventBusEventName'; | ||
|
||
type Events<T> = Record<EventType, T>; | ||
|
||
const emitter = mitt<Record<EventType, unknown>>(); | ||
|
||
export class ClientEventBus implements EventBus { | ||
public on<TEventBusEventName extends EventBusEventName<TEventBusEventType, TData>, | ||
TEventBusEventType, | ||
TData>(type: TEventBusEventName, handler: (e: TData) => void): void { | ||
emitter.on(type as TEventBusEventName, handler as Handler<Events<unknown>[TEventBusEventName]>); | ||
} | ||
|
||
public off<TEventBusEventName extends EventBusEventName<TEventBusEventType, TData>, | ||
TEventBusEventType, | ||
TData>(type: TEventBusEventName, handler?: (e: TData) => void): void { | ||
emitter.off(type as TEventBusEventName, handler as Handler<Events<unknown>[TEventBusEventName]>); | ||
} | ||
|
||
public emit<TEventBusEventName extends EventBusEventName<TEventBusEventType, TData>, | ||
TEventBusEventType, | ||
TData>(type: TEventBusEventName, e: TData): void; | ||
public emit<TEventBusEventName extends EventBusEventName<TEventBusEventType, TData>, | ||
TEventBusEventType, | ||
TData>(type: TEventBusEventName): void; | ||
public emit<TEventBusEventName extends EventBusEventName<TEventBusEventType, TData>, | ||
TEventBusEventType, | ||
TData>(type: TEventBusEventName, e?: TData): void { | ||
emitter.emit(type, e); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,22 @@ | ||
import mitt from 'mitt' | ||
import type { InjectionKey } from 'vue'; | ||
import { type EventBusEventName } from './eventBusEventNames/eventBusEventName'; | ||
|
||
// TODO: Handle stuff without an event bus or find a better typed solution at least | ||
export const eventBusInjectionKey: InjectionKey<EventBus> = Symbol('EventBus'); | ||
|
||
const emitter = mitt(); | ||
export interface EventBus { | ||
on<TEventBusEventName extends EventBusEventName<TEventBusEventType, TData>, | ||
TEventBusEventType, | ||
TData>(type: TEventBusEventName, handler: (e: TData) => void): void; | ||
|
||
const eventBus = { | ||
$on: emitter.on, | ||
$off: emitter.off, | ||
$emit: emitter.emit | ||
}; | ||
off<TEventBusEventName extends EventBusEventName<TEventBusEventType, TData>, | ||
TEventBusEventType, | ||
TData>(type: TEventBusEventName, handler?: (e: TData) => void): void; | ||
|
||
export default eventBus; | ||
emit<TEventBusEventName extends EventBusEventName<TEventBusEventType, TData>, | ||
TEventBusEventType, | ||
TData>(type: TEventBusEventName): void; | ||
|
||
emit<TEventBusEventName extends EventBusEventName<TEventBusEventType, TData>, | ||
TEventBusEventType, | ||
TData>(type: TEventBusEventName, e: TData): void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import type { DiplomaticStatus } from "solaris-common/src/api/types/common/diplomacy"; | ||
import { makeCastFunc } from "solaris-common/src/utilities/cast"; | ||
import type { EventBusEventName } from "./eventBusEventName"; | ||
|
||
export type DiplomacyEventBusEventType = { diplomacyEventBusEventType: 'diplomacyEventBusEventType' }; | ||
export type DiplomacyEventBusEventName<TData> = EventBusEventName<DiplomacyEventBusEventType, TData> & { diplomacyEventBusEventName: 'diplomacyEventBusEventName' } | ||
|
||
const toEventName: <TData>(value: string) => DiplomacyEventBusEventName<TData> = makeCastFunc(); | ||
|
||
export default class DiplomacyEventBusEventNames { | ||
private constructor() { }; | ||
|
||
public static readonly PlayerDiplomaticStatusChanged: DiplomacyEventBusEventName<{ diplomaticStatus: DiplomaticStatus<string> }> = toEventName('playerDiplomaticStatusChanged'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export type EventBusEventName<TEventBusEventType, TData> = string & { eventBusEventType?: TEventBusEventType, data?: TData, eventBusEventName: 'eventBusEventName' } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import type { GameState } from "solaris-common/src"; | ||
import { makeCastFunc } from "solaris-common/src/utilities/cast"; | ||
import type { EventBusEventName } from "./eventBusEventName"; | ||
|
||
export type GameEventBusEventType = { gameEventBusEventType: 'gameEventBusEventType' }; | ||
export type GameEventBusEventName<TData> = EventBusEventName<GameEventBusEventType, TData> & { gameEventBusEventName: 'gameEventBusEventName' } | ||
|
||
const toEventName: <TData>(value: string) => GameEventBusEventName<TData> = makeCastFunc(); | ||
|
||
export default class GameEventBusEventNames { | ||
private constructor() { }; | ||
|
||
public static readonly GameStarted: GameEventBusEventName<{ state: GameState<string> }> = toEventName('gameStarted'); | ||
public static readonly OnGameTick: GameEventBusEventName<void> = toEventName('onGameTick'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { makeCastFunc } from "solaris-common/src/utilities/cast"; | ||
import MENU_STATES from '../services/data/menuStates'; | ||
import type { EventBusEventName } from "./eventBusEventName"; | ||
|
||
export type MenuEventBusEventType = { menuEventBusEventType: 'menuEventBusEventType' }; | ||
export type MenuEventBusEventName<TData> = EventBusEventName<MenuEventBusEventType, TData> & { menuEventBusEventName: 'menuEventBusEventName' } | ||
|
||
const toEventName: <TData>(value: string) => MenuEventBusEventName<TData> = makeCastFunc(); | ||
|
||
export default class MenuEventBusEventNames { | ||
private constructor() { }; | ||
|
||
public static readonly OnMenuRequested: MenuEventBusEventName<{ menuState: MENU_STATES | null, menuArguments: unknown | null }> = toEventName('onMenuRequested'); | ||
|
||
public static readonly OnMenuChatSidebarRequested: MenuEventBusEventName<void> = toEventName('onMenuChatSidebarRequested'); | ||
|
||
public static readonly OnCreateNewConversationRequested: MenuEventBusEventName<{ participantIds?: string[] }> = toEventName('onCreateNewConversationRequested'); | ||
public static readonly OnViewConversationRequested: MenuEventBusEventName<{ conversationId: string, participantIds: string[] }> = toEventName('onViewConversationRequested'); | ||
public static readonly OnOpenInboxRequested: MenuEventBusEventName<void> = toEventName('onOpenInboxRequested'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { type ConversationMessageSentResult } from "solaris-common/src/api/types/common/conversationMessage"; | ||
import type { LedgerType } from "solaris-common/src/api/types/common/ledger"; | ||
import type { TradeEventTechnology } from "solaris-common/src/api/types/common/trade"; | ||
import { makeCastFunc } from "solaris-common/src/utilities/cast"; | ||
import { type EventBusEventName } from "./eventBusEventName"; | ||
|
||
export type PlayerEventBusEventType = { playerEventBusEventType: 'playerEventBusEventType' }; | ||
export type PlayerEventBusEventName<TData> = EventBusEventName<PlayerEventBusEventType, TData> & { playerEventBusEventName: 'playerEventBusEventName' } | ||
|
||
const toEventName: <TData>(value: string) => PlayerEventBusEventName<TData> = makeCastFunc(); | ||
|
||
export default class PlayerEventBusEventNames { | ||
private constructor() { }; | ||
|
||
public static readonly GameMessageSent: PlayerEventBusEventName<ConversationMessageSentResult<string>> = toEventName('gameMessageSent'); | ||
public static readonly GameConversationRead: PlayerEventBusEventName<{ conversationId: string, readByPlayerId: string }> = toEventName('gameConversationRead'); | ||
|
||
public static readonly GameConversationLeft: PlayerEventBusEventName<{ conversationId: string, playerId: string }> = toEventName('gameConversationLeft'); | ||
public static readonly GameConversationMessagePinned: PlayerEventBusEventName<{ conversationId: string, messageId: string }> = toEventName('gameConversationMessagePinned'); | ||
public static readonly GameConversationMessageUnpinned: PlayerEventBusEventName<{ conversationId: string, messageId: string }> = toEventName('gameConversationMessageUnpinned'); | ||
|
||
public static readonly PlayerEventRead: PlayerEventBusEventName<{ eventId: string }> = toEventName('playerEventRead'); | ||
public static readonly PlayerAllEventsRead: PlayerEventBusEventName<{}> = toEventName('playerAllEventsRead'); | ||
|
||
public static readonly PlayerCreditsReceived: PlayerEventBusEventName<{ playerId: string, type: string, date: Date, data: { fromPlayerId: string, toPlayerId: string, credits: number } }> = toEventName('playerCreditsReceived'); | ||
public static readonly PlayerCreditsSpecialistsReceived: PlayerEventBusEventName<{ playerId: string, type: string, date: Date, data: { fromPlayerId: string, toPlayerId: string, creditsSpecialists: number } }> = toEventName('playerCreditsSpecialistsReceived'); | ||
public static readonly PlayerTechnologyReceived: PlayerEventBusEventName<{ playerId: string, type: string, date: Date, data: { fromPlayerId: string, toPlayerId: string, technology: TradeEventTechnology } }> = toEventName('playerTechnologyReceived'); | ||
public static readonly PlayerRenownReceived: PlayerEventBusEventName<{ playerId: string, type: string, date: Date, data: { fromPlayerId: string, toPlayerId: string, renown: number } }> = toEventName('playerRenownReceived'); | ||
|
||
public static readonly PlayerDebtAdded: PlayerEventBusEventName<{ debtorPlayerId: string, creditorPlayerId: string, amount: number, ledgerType: LedgerType }> = toEventName('playerDebtAdded'); | ||
public static readonly PlayerDebtForgiven: PlayerEventBusEventName<{ debtorPlayerId: string, creditorPlayerId: string, amount: number, ledgerType: LedgerType }> = toEventName('playerDebtForgiven'); | ||
public static readonly PlayerDebtSettled: PlayerEventBusEventName<{ debtorPlayerId: string, creditorPlayerId: string, amount: number, ledgerType: LedgerType }> = toEventName('playerDebtSettled'); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import "@/assets/styles.css" | ||
import $ from 'jquery' | ||
import 'pixi-viewport' | ||
import 'pixi.js' | ||
import { io } from 'socket.io-client' | ||
import { createApp } from 'vue' | ||
import ToastPlugin from "vue-toast-notification" | ||
import 'vue-toast-notification/dist/theme-default.css' | ||
import App from './App.vue' | ||
import { ClientEventBus } from "./clientEventBus" | ||
import { eventBusInjectionKey, type EventBus } from './eventBus' | ||
import router from './router' | ||
import GameHelper from './services/gameHelper' | ||
import { PlayerClientSocketEmitter, playerClientSocketEmitterInjectionKey } from './socketEmitters/player' | ||
import { DiplomacyClientSocketHandler } from './socketHandlers/diplomacy' | ||
import { GameClientSocketHandler } from './socketHandlers/game' | ||
import { PlayerClientSocketHandler } from "./socketHandlers/player" | ||
import { createSolarisStore } from './store' | ||
|
||
// Note: This was done to get around an issue where the Steam client | ||
// had bootstrap as undefined. This also affects the UI template we're using, | ||
// we are forced to bring in Bootstrap and FontAwesome manually as a dependency | ||
// instead of using the vendor files provided by the template. | ||
// DO NOT use top-level await since that silently breaks the bundle | ||
import('bootstrap/dist/js/bootstrap.bundle.js').then((mod) => window.bootstrap = mod); | ||
declare var bootstrap: any; // Hnnngh. | ||
import('../public/assets/js/app.min.js') | ||
|
||
const socketUrl: string = import.meta.env.VUE_APP_SOCKETS_HOST; | ||
|
||
window.$ = $; | ||
|
||
window._solaris = { | ||
errors: [] | ||
}; | ||
|
||
const app = createApp(App); | ||
|
||
app.config.errorHandler = (err, vm, info) => { | ||
if (err instanceof Error) { | ||
window._solaris.errors.push(`Vue error: ${err.message}\n ${err.cause} ${info}\n ${err.stack}`); | ||
} | ||
else { | ||
window._solaris.errors.push(`Unknown error: ${err}`); | ||
} | ||
|
||
console.error(err); | ||
}; | ||
|
||
window.addEventListener("error", (ev) => { | ||
window._solaris.errors.push(ev.error + ' ' + ev.message); | ||
}); | ||
|
||
window.addEventListener("unhandledrejection", (event) => { | ||
window._solaris.errors.push(event.reason); | ||
reportError(event.reason); | ||
}); | ||
|
||
const eventBus: EventBus = new ClientEventBus(); | ||
|
||
let store = createSolarisStore(eventBus); | ||
|
||
app.use(store); | ||
|
||
app.use(ToastPlugin); | ||
|
||
let socket = io(socketUrl, { withCredentials: true }); | ||
|
||
socket.on('connect', () => { | ||
console.log('Socket connection established.'); | ||
}); | ||
|
||
socket.io.on('error', e => { | ||
console.error('Socket.io error.'); | ||
console.error(e); | ||
}); | ||
|
||
export const diplomacyClientSocketHandler: DiplomacyClientSocketHandler = new DiplomacyClientSocketHandler(socket, eventBus); | ||
export const gameClientSocketHandler: GameClientSocketHandler = new GameClientSocketHandler(socket, store, app.config.globalProperties.$toast, eventBus); | ||
export const playerClientSocketHandler: PlayerClientSocketHandler = new PlayerClientSocketHandler(socket, store, eventBus); | ||
|
||
const playerClientSocketEmitter: PlayerClientSocketEmitter = new PlayerClientSocketEmitter(socket); | ||
|
||
app.provide(playerClientSocketEmitterInjectionKey, playerClientSocketEmitter); | ||
app.provide(eventBusInjectionKey, eventBus); | ||
|
||
socket.io.on('reconnect', () => { | ||
let gameId = store.state.game?._id; | ||
|
||
if (gameId != null) { | ||
let player = GameHelper.getUserPlayer(store.state.game) | ||
|
||
console.log('Rejoining game room.'); | ||
|
||
playerClientSocketEmitter.emitGameRoomJoined({ | ||
gameId: gameId, | ||
playerId: player?._id | ||
}); | ||
} | ||
}); | ||
|
||
|
||
app.config.globalProperties.$confirm = async function(title, text, confirmText = 'Yes', cancelText = 'No', hideCancelButton = false, cover = false) { | ||
return this.$store.dispatch('confirm', { | ||
titleText: title, | ||
text, | ||
confirmText, | ||
cancelText, | ||
hideCancelButton, | ||
cover | ||
}) | ||
} | ||
|
||
app.config.globalProperties.$isHistoricalMode = function() { | ||
return this.$store.state.tick !== this.$store.state.game.state.tick | ||
} | ||
|
||
app.config.globalProperties.$isMobile = function () { | ||
return window.matchMedia('only screen and (max-width: 576px)').matches | ||
} | ||
|
||
app.directive('tooltip', function(el, binding) { | ||
new bootstrap.Tooltip($(el), { | ||
title: binding.value, | ||
placement: binding.arg, | ||
trigger: 'hover' | ||
}) | ||
}) | ||
|
||
app.use(router); | ||
|
||
app.mount('#app'); |
Oops, something went wrong.