diff --git a/src/client.ts b/src/client.ts index d16fff8..2bd414d 100644 --- a/src/client.ts +++ b/src/client.ts @@ -675,7 +675,16 @@ export class BikeTagClient extends EventEmitter { opts, DataTypes.queue ) - const clientMethod = api.queueTag + let clientMethod = api.queueTag + + switch (options.source) { + case AvailableApis.imgur: + clientMethod = clientMethod.bind({ + getQueue: this.getPassthroughApiMethod(api.getQueue, client), + getTags: this.getPassthroughApiMethod(api.getTags, client), + }) + break + } /// If the client adapter implements the method diff --git a/src/imgur/queueTag.ts b/src/imgur/queueTag.ts index dea0f98..bacd842 100644 --- a/src/imgur/queueTag.ts +++ b/src/imgur/queueTag.ts @@ -12,10 +12,12 @@ import { Tag } from '../common/schema' import { queueTagPayload } from '../common/payloads' import { AvailableApis, HttpStatusCode } from '../common/enums' import { UpdateImagePayload } from 'imgur/lib/image' +import TinyCache from 'tinycache' export async function queueTag( client: ImgurClient, - payload: queueTagPayload + payload: queueTagPayload, + cache?: typeof TinyCache ): Promise> { const uploadFoundImage = payload?.foundImage && !(payload?.foundImageUrl?.length > 0) @@ -38,66 +40,87 @@ export async function queueTag( let data let error - if (isCompleteQueuedTag) { - /// Remove the playerId so that it can't be mimicked - /// Update just the mystery image (current.tagnumber + 1) - const mysteryTagUpdatePayload = getUpdateTagPayloadFromTagData( - payload, - true - ) - const mysteryTagUpdateResponse = await client.updateImage( - mysteryTagUpdatePayload as UpdateImagePayload - ) + const queuedTags = await this.getQueue(undefined, cache) + const playerAlreadyQueued = queuedTags.data?.find((t) => { + return isCompleteQueuedTag + ? t.mysteryPlayer === payload.mysteryPlayer + : t.foundPlayer === payload.foundPlayer + }) + const currentTags = await this.getTags(undefined, cache) + const currentTag = currentTags?.data?.length ? currentTags.data[0] : undefined - /// Update just the found image (current.tagnumber) - payload.tagnumber = payload.tagnumber - 1 - const foundTagUpdatePayload = getUpdateTagPayloadFromTagData(payload) - const foundTagUpdateResponse = await client.updateImage( - foundTagUpdatePayload as UpdateImagePayload - ) - if (foundTagUpdateResponse.success && mysteryTagUpdateResponse.success) { - data = payload - success = true - } else { - success = false - error = `found: ${foundTagUpdateResponse.data}, mystery: ${mysteryTagUpdateResponse.data}` - } - } else if (isFoundQueuedTag || isMysteryQueuedTag) { - const queuedTagUploadPayload = await getQueueTagImagePayloadFromTagData( - payload as queueTagImagePayload, - isMysteryQueuedTag - ) + if (playerAlreadyQueued) { + data = payload + success = false + error = 'player already has queued tag' + status = HttpStatusCode.Conflict + } else if (currentTag.mysteryPlayer === payload.foundPlayer) { + data = payload + success = false + error = 'player created previous round' + status = HttpStatusCode.Conflict + } else { + if (isCompleteQueuedTag) { + /// Remove the playerId so that it can't be mimicked + /// Update just the mystery image (current.tagnumber + 1) + const mysteryTagUpdatePayload = getUpdateTagPayloadFromTagData( + payload, + true + ) + const mysteryTagUpdateResponse = await client.updateImage( + mysteryTagUpdatePayload as UpdateImagePayload + ) - if (isValidUploadTagImagePayload(queuedTagUploadPayload)) { - const queuedTagImageUploadResponse = await client.upload( - queuedTagUploadPayload as Payload + /// Update just the found image (current.tagnumber) + payload.tagnumber = payload.tagnumber - 1 + const foundTagUpdatePayload = getUpdateTagPayloadFromTagData(payload) + const foundTagUpdateResponse = await client.updateImage( + foundTagUpdatePayload as UpdateImagePayload ) - if (queuedTagImageUploadResponse.success) { - const queuedTagImage = queuedTagImageUploadResponse.data - if (queuedTagImage) { - if (isFoundQueuedTag) { - payload.foundImage = undefined - payload.foundImageUrl = queuedTagImage.link - } else if (isMysteryQueuedTag) { - payload.mysteryImage = undefined - payload.mysteryImageUrl = queuedTagImage.link + if (foundTagUpdateResponse.success && mysteryTagUpdateResponse.success) { + data = payload + success = true + } else { + success = false + error = `found: ${foundTagUpdateResponse.data}, mystery: ${mysteryTagUpdateResponse.data}` + } + } else if (isFoundQueuedTag || isMysteryQueuedTag) { + const queuedTagUploadPayload = await getQueueTagImagePayloadFromTagData( + payload as queueTagImagePayload, + isMysteryQueuedTag + ) + + if (isValidUploadTagImagePayload(queuedTagUploadPayload)) { + const queuedTagImageUploadResponse = await client.upload( + queuedTagUploadPayload as Payload + ) + if (queuedTagImageUploadResponse.success) { + const queuedTagImage = queuedTagImageUploadResponse.data + if (queuedTagImage) { + if (isFoundQueuedTag) { + payload.foundImage = undefined + payload.foundImageUrl = queuedTagImage.link + } else if (isMysteryQueuedTag) { + payload.mysteryImage = undefined + payload.mysteryImageUrl = queuedTagImage.link + } } + data = createTagObject(payload) + } else { + error = queuedTagImageUploadResponse.data } - data = createTagObject(payload) + + status = queuedTagImageUploadResponse.status + success = queuedTagImageUploadResponse.success } else { - error = queuedTagImageUploadResponse.data + success = false + status = HttpStatusCode.BadRequest } - - status = queuedTagImageUploadResponse.status - success = queuedTagImageUploadResponse.success } else { + data = createTagObject(payload) success = false - status = HttpStatusCode.BadRequest + status = HttpStatusCode.NoContent } - } else { - data = createTagObject(payload) - success = false - status = HttpStatusCode.NoContent } return {