-
-
Notifications
You must be signed in to change notification settings - Fork 274
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(game/api/onCall): refactor and allow for multiple handlers p…
…er number
- Loading branch information
1 parent
666429a
commit 3407bec
Showing
5 changed files
with
195 additions
and
90 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { | ||
ActiveCall, | ||
CallMiddlewareInvokable, | ||
IncomingCallerCtx, | ||
InitializeCallDTO, | ||
OnCallExportCtx, OnCallStatus | ||
} from "@typings/call"; | ||
import OncallService from './oncall.service'; | ||
import MessagesService from '../../messages/messages.service'; | ||
import CallService from '../calls.service'; | ||
import { callLogger } from '../calls.utils'; | ||
import { PromiseEventResp, PromiseRequest } from '../../lib/PromiseNetEvents/promise.types'; | ||
|
||
const exp = global.exports; | ||
|
||
export const OnCallMap = new Map<string, (ctx: OnCallExportCtx) => void>(); | ||
|
||
/* | ||
Will add middleware for targeted numbers with the following context: | ||
interface IncomingCallerCtx { | ||
source: number; | ||
number: string; | ||
name: string; | ||
} | ||
export interface OnCallExportCtx { | ||
incomingCaller: IncomingCallerCtx; | ||
exit: () => void; | ||
next: () => void; | ||
reply: (msg: string) => void; | ||
forward: (tgt: string) => void; | ||
} | ||
*/ | ||
exp('onCall', (tgtNumber: string, cb: CallMiddlewareInvokable) => { | ||
const resourceName = GetInvokingResource() | ||
const handler = new CallMiddleware(cb, resourceName, tgtNumber.toString()) | ||
callLogger.debug(`Resource [${resourceName}] registered an onCall handler for number [${tgtNumber}]`) | ||
OncallService.addHandler(handler) | ||
}); | ||
|
||
export class CallMiddleware { | ||
constructor( | ||
private funcRef: CallMiddlewareInvokable, | ||
public hostResource: string, | ||
public target: string, | ||
) {} | ||
|
||
invoke( | ||
incomingCaller: IncomingCallerCtx, | ||
reqObj: PromiseRequest<InitializeCallDTO>, | ||
resp: PromiseEventResp<ActiveCall>, | ||
) { | ||
return new Promise<OnCallStatus>((resolve, reject) => | ||
this.funcRef({ | ||
receiverNumber: reqObj.data.receiverNumber, | ||
incomingCaller, | ||
next: () => { | ||
resolve(OnCallStatus.NEXT); | ||
return; | ||
}, | ||
exit: () => { | ||
reject(); | ||
return; | ||
}, | ||
reply: (message) => { | ||
MessagesService.handleEmitMessage({ | ||
senderNumber: reqObj.data.receiverNumber, | ||
targetNumber: incomingCaller.number, | ||
message, | ||
}); | ||
}, | ||
forward: (receiverNumber: string, isAnonymous = false) => { | ||
CallService.handleInitializeCall( | ||
{ ...reqObj, data: { receiverNumber, isAnonymous } }, | ||
resp, | ||
) | ||
.catch((e) => { | ||
resp({ status: 'error', errorMsg: 'SERVER_ERROR' }); | ||
callLogger.error(`Error occured handling init call: ${e.message}`); | ||
}) | ||
.then(() => { | ||
resolve(OnCallStatus.FORWARD) | ||
return; | ||
}) | ||
.catch(reject); | ||
}, | ||
}), | ||
); | ||
} | ||
} | ||
|
||
on("onResourceStop", (resource: string) => { | ||
OncallService.resetResource(resource) | ||
}) |
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,89 @@ | ||
import { ActiveCall, CallEvents, InitializeCallDTO, OnCallStatus } from "@typings/call"; | ||
import { CallMiddleware } from "./index"; | ||
import { PromiseEventResp, PromiseRequest } from "../../lib/PromiseNetEvents/promise.types"; | ||
import PlayerService from "../../players/player.service"; | ||
import { uuidv4 } from "../../../utils/fivem"; | ||
import { callLogger } from "../calls.utils"; | ||
|
||
class OnCallService { | ||
private callHandlers: Map<string, CallMiddleware[]> | ||
private resourcesTracked: Set<string> | ||
|
||
constructor() { | ||
this.callHandlers = new Map() | ||
this.resourcesTracked = new Set() | ||
} | ||
|
||
addHandler(handler: CallMiddleware) { | ||
this.resourcesTracked.add(handler.hostResource) | ||
|
||
if (this.callHandlers.has(handler.target)){ | ||
const handlerList = this.callHandlers.get(handler.target) | ||
handlerList.push(handler) | ||
|
||
return | ||
} | ||
|
||
this.callHandlers.set(handler.target, [handler]) | ||
} | ||
|
||
// Keep a set containing all the resources we are tracking so that we are not doing an O(n^2) compute unnecessarily | ||
resetResource(resource: string) { | ||
if (!this.resourcesTracked.has(resource)) return; | ||
|
||
this.callHandlers.forEach((value, key, map) => { | ||
const newList = value.filter(c => c.hostResource !== resource) | ||
map.set(key, newList) | ||
}) | ||
} | ||
|
||
async handle( | ||
reqObj: PromiseRequest<InitializeCallDTO>, | ||
resp: PromiseEventResp<ActiveCall> | ||
) { | ||
callLogger.debug("invoking onCall for number", reqObj.data.receiverNumber) | ||
if (!this.callHandlers.has(reqObj.data.receiverNumber)) { | ||
return | ||
} | ||
|
||
const caller = PlayerService.getPlayer(reqObj.source); | ||
|
||
const incomingCaller = { | ||
source: reqObj.source, | ||
name: caller.getName(), | ||
number: caller.getPhoneNumber(), | ||
}; | ||
|
||
const handlerList = this.callHandlers.get(reqObj.data.receiverNumber) | ||
console.log(handlerList.length) | ||
for (const handler of handlerList) { | ||
try { | ||
const status = await handler.invoke(incomingCaller, reqObj, resp) | ||
if (status === OnCallStatus.FORWARD) { | ||
break; | ||
} | ||
} catch (e) { | ||
const tempSaveCallObj = { | ||
identifier: uuidv4(), | ||
isTransmitter: true, | ||
transmitter: incomingCaller.number, | ||
receiver: reqObj.data.receiverNumber, | ||
is_accepted: false, | ||
isUnavailable: true, | ||
start: Math.floor(new Date().getTime() / 1000).toString(), | ||
}; | ||
|
||
resp({ | ||
status: 'ok', | ||
data: tempSaveCallObj, | ||
}); | ||
|
||
return setTimeout(() => { | ||
emitNet(CallEvents.WAS_REJECTED, reqObj.source, tempSaveCallObj); | ||
}, 2000); | ||
} | ||
} | ||
} | ||
} | ||
|
||
export default new OnCallService() |
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