HallService.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { AppKernel } from '../../app/AppKernel';
  2. import { APP_SERVER } from '../../define/Define';
  3. import { ColyseusRoomClient } from '../../network/colyseus/ColyseusRoomClient';
  4. const CASH_BASE = 100;
  5. export interface HallMessage {
  6. cmd?: string;
  7. data?: Record<string, unknown>;
  8. [key: string]: unknown;
  9. }
  10. export interface HallPayFinishMessage extends HallMessage {
  11. cmd: 'pay_finish';
  12. data?: {
  13. Golds?: number | string;
  14. PayNum?: number | string;
  15. event?: string;
  16. params?: unknown;
  17. [key: string]: unknown;
  18. };
  19. }
  20. export interface HallCallClientMessage extends HallMessage {
  21. cmd: 'call_client';
  22. data?: {
  23. type?: 'track' | 'refresh_mail' | 'start_change' | string;
  24. Golds?: number | string;
  25. event?: string;
  26. params?: unknown;
  27. [key: string]: unknown;
  28. };
  29. }
  30. class HallService {
  31. private client: ColyseusRoomClient | null = null;
  32. private serverUrl = '';
  33. async connect(serverUrl?: string): Promise<boolean> {
  34. const mainStore = AppKernel.stores.mainStore;
  35. if (!mainStore.isLogin || mainStore.userID <= 0) return false;
  36. const nextUrl = serverUrl || mainStore.hallServerUrl || APP_SERVER.SERVER_URL;
  37. console.log('[HallService] endpoint:', JSON.stringify(nextUrl));
  38. if (!nextUrl) {
  39. console.warn('[HallService] Hall server URL is empty');
  40. return false;
  41. }
  42. if (!this.client || this.serverUrl !== nextUrl) {
  43. if (this.client) await this.client.disconnect();
  44. this.serverUrl = nextUrl;
  45. this.client = this.createClient(nextUrl);
  46. }
  47. return this.client.connect();
  48. }
  49. async disconnect(): Promise<void> {
  50. const client = this.client;
  51. this.client = null;
  52. this.serverUrl = '';
  53. if (client) await client.disconnect();
  54. }
  55. sendChat(message: unknown): boolean {
  56. return this.send('chat', message);
  57. }
  58. sendRegistration(): boolean {
  59. const user = AppKernel.stores.mainStore.userInfo;
  60. if (!user) return false;
  61. const { UserID, GlobalUID, FaceID, NickName } = user;
  62. return this.send('id', { UserID, GlobalUID, FaceID, NickName });
  63. }
  64. sendState(): boolean {
  65. return this.send('state', { in_game: AppKernel.stores.mainStore.gameID });
  66. }
  67. private createClient(serverUrl: string): ColyseusRoomClient {
  68. return new ColyseusRoomClient(APP_SERVER.ROOM_HALL, serverUrl, {
  69. onConnected: () => {
  70. AppKernel.stores.mainStore.setServerKick(false);
  71. AppKernel.events.emit('hall:connected');
  72. this.sendRegistration();
  73. },
  74. onDisconnected: (code) => AppKernel.events.emit('hall:disconnected', { code }),
  75. onTimeout: () => AppKernel.events.emit('hall:timeout'),
  76. onMessage: (type, message) => this.onMessage(type, message),
  77. });
  78. }
  79. private send(type: string, message: unknown = ''): boolean {
  80. return this.client?.send(type, message) ?? false;
  81. }
  82. private onMessage(type: string, rawMessage: unknown): void {
  83. const message = this.asMessage(rawMessage);
  84. AppKernel.events.emit('hall:message', { type, message });
  85. switch (type) {
  86. case 'operate':
  87. this.handleOperate(message);
  88. break;
  89. case 'roger':
  90. this.handleRoger(message);
  91. break;
  92. }
  93. }
  94. private handleOperate(message: HallMessage): void {
  95. switch (message.cmd) {
  96. case 'id':
  97. this.sendState();
  98. break;
  99. case 'kick':
  100. AppKernel.stores.mainStore.setServerKick(true);
  101. AppKernel.events.emit('hall:kicked', message);
  102. break;
  103. }
  104. }
  105. private handleRoger(message: HallMessage): void {
  106. switch (message.cmd) {
  107. case 'pay_finish': {
  108. const payMessage = message as HallPayFinishMessage;
  109. this.updateBalance(payMessage.data?.Golds);
  110. AppKernel.events.emit('hall:pay-finished', payMessage);
  111. break;
  112. }
  113. case 'call_client': {
  114. const callMessage = message as HallCallClientMessage;
  115. if (callMessage.data?.type === 'start_change') {
  116. this.updateBalance(callMessage.data.Golds);
  117. }
  118. AppKernel.events.emit('hall:call-client', callMessage);
  119. break;
  120. }
  121. }
  122. }
  123. private updateBalance(rawGolds: number | string | undefined): void {
  124. if (rawGolds === undefined || rawGolds === null || rawGolds === '') return;
  125. const balance = Number(rawGolds) / CASH_BASE;
  126. AppKernel.stores.mainStore.updateHallBalance(balance);
  127. }
  128. private asMessage(message: unknown): HallMessage {
  129. if (message && typeof message === 'object') return message as HallMessage;
  130. return { data: { value: message } };
  131. }
  132. }
  133. export const hallService = new HallService();