|
1 | 1 | import { ipcMain } from 'electron';
|
2 | 2 | import { createLogger } from '../logger';
|
| 3 | +import type { SGEGameCode } from '../sge'; |
| 4 | +import { SGEServiceImpl } from '../sge'; |
| 5 | +import { store } from '../store'; |
3 | 6 | import type { Dispatcher } from '../types';
|
4 | 7 | import type {
|
5 | 8 | IpcHandlerRegistry,
|
6 | 9 | IpcInvokableEvent,
|
7 | 10 | IpcInvokeHandler,
|
| 11 | + SGEListAccountsResponse, |
| 12 | + SGEListCharactersResponse, |
8 | 13 | } from './ipc.types';
|
9 | 14 |
|
10 | 15 | const logger = createLogger('ipc');
|
@@ -69,75 +74,110 @@ export class IpcController {
|
69 | 74 | ): Promise<void> => {
|
70 | 75 | const { gameCode, username, password } = args[0];
|
71 | 76 |
|
72 |
| - // TODO |
73 |
| - logger.info('sgeAddAccountHandler', { gameCode, username }); |
| 77 | + logger.debug('sgeAddAccountHandler', { gameCode, username }); |
| 78 | + |
| 79 | + const key = this.getSgeAccountStoreKey({ gameCode, username }); |
| 80 | + await store.set(key, password, { encrypted: true }); |
74 | 81 | };
|
75 | 82 |
|
76 | 83 | private sgeRemoveAccountHandler: IpcInvokeHandler<'sgeRemoveAccount'> =
|
77 | 84 | async (args): Promise<void> => {
|
78 | 85 | const { gameCode, username } = args[0];
|
79 | 86 |
|
80 |
| - // TODO |
81 |
| - logger.info('sgeRemoveAccountHandler', { gameCode, username }); |
| 87 | + logger.debug('sgeRemoveAccountHandler', { gameCode, username }); |
| 88 | + |
| 89 | + const key = this.getSgeAccountStoreKey({ gameCode, username }); |
| 90 | + await store.remove(key); |
82 | 91 | };
|
83 | 92 |
|
84 | 93 | private sgeListAccountsHandler: IpcInvokeHandler<'sgeListAccounts'> = async (
|
85 | 94 | args
|
86 |
| - ): Promise< |
87 |
| - Array<{ |
88 |
| - gameCode: string; |
89 |
| - username: string; |
90 |
| - }> |
91 |
| - > => { |
| 95 | + ): Promise<SGEListAccountsResponse> => { |
92 | 96 | const { gameCode } = args[0];
|
93 | 97 |
|
94 |
| - // TODO |
95 |
| - logger.info('sgeListAccountsHandler', { gameCode }); |
| 98 | + logger.debug('sgeListAccountsHandler', { gameCode }); |
| 99 | + |
| 100 | + const keys = await store.keys(); |
| 101 | + const keyPrefix = this.getSgeAccountStoreKey({ gameCode, username: '' }); |
| 102 | + |
| 103 | + const accounts = keys |
| 104 | + .filter((key) => { |
| 105 | + return key.startsWith(keyPrefix); |
| 106 | + }) |
| 107 | + .map((key) => { |
| 108 | + const username = key.slice(keyPrefix.length); |
| 109 | + return { gameCode, username }; |
| 110 | + }); |
96 | 111 |
|
97 |
| - return []; |
| 112 | + return accounts; |
98 | 113 | };
|
99 | 114 |
|
100 | 115 | private sgeListCharactersHandler: IpcInvokeHandler<'sgeListCharacters'> =
|
101 |
| - async ( |
102 |
| - args |
103 |
| - ): Promise< |
104 |
| - Array<{ |
105 |
| - id: string; |
106 |
| - name: string; |
107 |
| - }> |
108 |
| - > => { |
| 116 | + async (args): Promise<SGEListCharactersResponse> => { |
109 | 117 | const { gameCode, username } = args[0];
|
110 | 118 |
|
111 |
| - // TODO |
112 |
| - logger.info('sgeListCharactersHandler', { gameCode, username }); |
| 119 | + logger.debug('sgeListCharactersHandler', { gameCode, username }); |
| 120 | + |
| 121 | + const key = this.getSgeAccountStoreKey({ gameCode, username }); |
| 122 | + const password = await store.get<string>(key); |
| 123 | + |
| 124 | + if (password) { |
| 125 | + const sgeService = new SGEServiceImpl({ |
| 126 | + gameCode: gameCode as SGEGameCode, |
| 127 | + username, |
| 128 | + password, |
| 129 | + }); |
| 130 | + return sgeService.listCharacters(); |
| 131 | + } |
113 | 132 |
|
114 |
| - return []; |
| 133 | + throw new Error(`[IPC:SGE:ACCOUNT:NOT_FOUND] ${gameCode}:${username}`); |
115 | 134 | };
|
116 | 135 |
|
117 | 136 | private gamePlayCharacterHandler: IpcInvokeHandler<'gamePlayCharacter'> =
|
118 | 137 | async (args): Promise<void> => {
|
119 | 138 | const { gameCode, username, characterName } = args[0];
|
120 | 139 |
|
121 |
| - logger.info('gamePlayCharacterHandler', { |
| 140 | + logger.debug('gamePlayCharacterHandler', { |
122 | 141 | gameCode,
|
123 | 142 | username,
|
124 | 143 | characterName,
|
125 | 144 | });
|
126 | 145 |
|
127 |
| - // TODO look up sge credentials for { gameCode, username } |
128 |
| - // TODO use sge service to get character game play credentials |
129 |
| - // TODO Game.initInstance({ credentials, dispatch }); |
130 |
| - // TODO game instance emit data via dispatch function |
131 |
| - // TODO renderer listens for game data and updates ui accordingly |
| 146 | + const key = this.getSgeAccountStoreKey({ gameCode, username }); |
| 147 | + const password = await store.get<string>(key); |
| 148 | + |
| 149 | + if (password) { |
| 150 | + const sgeService = new SGEServiceImpl({ |
| 151 | + gameCode: gameCode as SGEGameCode, |
| 152 | + username, |
| 153 | + password, |
| 154 | + }); |
| 155 | + |
| 156 | + const credentials = await sgeService.loginCharacter(characterName); |
| 157 | + |
| 158 | + // TODO Game.initInstance({ credentials, dispatch }); |
| 159 | + // TODO game instance emit data via dispatch function |
| 160 | + // TODO renderer listens for game data and updates ui accordingly |
| 161 | + } |
| 162 | + |
| 163 | + throw new Error(`[IPC:SGE:ACCOUNT:NOT_FOUND] ${gameCode}:${username}`); |
132 | 164 | };
|
133 | 165 |
|
134 | 166 | private gameSendCommandHandler: IpcInvokeHandler<'gameSendCommand'> = async (
|
135 | 167 | args
|
136 | 168 | ): Promise<void> => {
|
137 | 169 | const command = args[0];
|
138 | 170 |
|
139 |
| - logger.info('gameSendCommandHandler', { command }); |
| 171 | + logger.debug('gameSendCommandHandler', { command }); |
140 | 172 |
|
141 | 173 | // TODO Game.getInstance().sendCommand(command);
|
142 | 174 | };
|
| 175 | + |
| 176 | + private getSgeAccountStoreKey(options: { |
| 177 | + gameCode: string; |
| 178 | + username: string; |
| 179 | + }): string { |
| 180 | + const { gameCode, username } = options; |
| 181 | + return `sge.account.${gameCode}.${username}`.toLowerCase(); |
| 182 | + } |
143 | 183 | }
|
0 commit comments