Skip to content

Commit

Permalink
Merge branch 'v5' into v5-chore-update-discord-instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
itsjesski committed Sep 15, 2023
2 parents a459266 + aa1e7ef commit 3b54eef
Show file tree
Hide file tree
Showing 20 changed files with 344 additions and 97 deletions.
4 changes: 4 additions & 0 deletions src/backend/chat/commands/builtin/steam/steam-access.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ const getSteamGameDetails = async (requestedGame) => {
gameDetails.releaseDate = foundGame.release_date.date;
}

if (foundGame.short_description) {
gameDetails.shortDescription = foundGame.short_description;
}

return gameDetails;
};

Expand Down
5 changes: 3 additions & 2 deletions src/backend/chat/commands/builtin/steam/steam.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const steam = {
outputTemplate: {
type: "string",
title: "Output Template",
tip: "Variables: {gameName}, {price}, {releaseDate}, {metaCriticScore}, {steamUrl}",
tip: "Variables: {gameName}, {price}, {releaseDate}, {metaCriticScore}, {steamUrl}, {steamShortDescription}",
default: `{gameName} (Price: {price} - Released: {releaseDate} - Metacritic: {metaCriticScore}) {steamUrl}`,
useTextArea: true
}
Expand All @@ -49,7 +49,8 @@ const steam = {
.replace("{price}", gameDetails.price || "Unknown")
.replace("{releaseDate}", gameDetails.releaseDate || "Unknown")
.replace("{metaCriticScore}", gameDetails.score || "Unknown")
.replace("{steamUrl}", gameDetails.url);
.replace("{steamUrl}", gameDetails.url)
.replace("{steamShortDescription}", gameDetails.shortDescription || "Unknown");
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/backend/common/handlers/fileWriterProcessor.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict";

const fs = require("fs-extra");
const path = require("path");
const logger = require("../../logwrapper");

function doesTextExistInFile(filepath, text) {
Expand Down Expand Up @@ -75,6 +76,7 @@ exports.run = async effect => {
fs.appendFileSync(effect.filepath, text + "\n", "utf8");
}
} else {
fs.ensureDirSync(path.dirname(effect.filepath));
fs.appendFileSync(effect.filepath, text + "\n", "utf8");
}
} else if (effect.writeMode === "delete") {
Expand Down
12 changes: 12 additions & 0 deletions src/backend/effects/builtin/control-emulation.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ const effect = {
"f10",
"f11",
"f12",
"f13",
"f14",
"f15",
"f16",
"f17",
"f18",
"f19",
"f20",
"f21",
"f22",
"f23",
"f24",
"alt",
"control",
"shift",
Expand Down
88 changes: 28 additions & 60 deletions src/backend/effects/builtin/play-video.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const accountAccess = require("../../common/account-access");
const util = require("../../utility");
const fs = require('fs-extra');
const path = require("path");
const frontendCommunicator = require('../../common/frontend-communicator');
const { wait } = require("../../utility");
const { parseYoutubeId } = require("../../../shared/youtube-url-parser");

/**
* The Play Video effect
Expand Down Expand Up @@ -366,7 +369,7 @@ const playVideo = {
/**@type {import('@twurple/api').HelixClip} */
let clip;
if (effect.videoType === "Twitch Clip") {
clipId = effect.twitchClipUrl.replace("https://clips.twitch.tv/", "");
clipId = effect.twitchClipUrl.split("/").pop();
try {
clip = await client.clips.getClipById(clipId);
} catch (error) {
Expand Down Expand Up @@ -439,40 +442,31 @@ const playVideo = {
}

let resourceToken;
let duration;
if (effect.videoType === "YouTube Video") {
resourceToken = resourceTokenManager.storeResourcePath(data.filepath, effect.length);
const youtubeData = parseYoutubeId(data.youtubeId);
data.youtubeId = youtubeData.id;
const result = await frontendCommunicator.fireEventAsync("getYoutubeVideoDuration", data.youtubeId);
if (!isNaN(result)) {
duration = result;
}
if (data.videoStarttime == null || data.videoStarttime == "" || data.videoStarttime == 0) {
data.videoStarttime = youtubeData.startTime;
}
} else {
const durationToken = resourceTokenManager.storeResourcePath(data.filepath, 5);

const durationPromise = new Promise(async (resolve, reject) => {
const listener = (event) => {
try {
if (event.name === "video-duration" && event.data.resourceToken === durationToken) {
webServer.removeListener("overlay-event", listener);
resolve(event.data.duration);
}
} catch (err) {
logger.error("Error while trying to process overlay-event for getVideoDuration: ", err);
reject(err);
}
};
webServer.on("overlay-event", listener);
});

webServer.sendToOverlay("getVideoDuration", {
resourceToken: durationToken,
overlayInstance: data.overlayInstance
});

const duration = await durationPromise;
resourceToken = resourceTokenManager.storeResourcePath(data.filepath, duration + 5);
logger.info(`Retrieved duration for video: ${duration}`);
const result = await frontendCommunicator.fireEventAsync("getVideoDuration", data.filepath);
if (!isNaN(result)) {
duration = result;
}
resourceToken = resourceTokenManager.storeResourcePath(data.filepath, duration);
}

data.resourceToken = resourceToken;

webServer.sendToOverlay("video", data);
if (effect.wait) {
if (effect.wait && effect.videoType === "YouTube Video") {
// Use overlay callback for youtube video, needs local way to get duration for production.
// If effect is ran with "Wait for video to finish" while overlay is not open, it may freeze an effect queue.
await new Promise(async (resolve, reject) => {
const listener = (event) => {
try {
Expand All @@ -487,6 +481,12 @@ const playVideo = {
};
webServer.on("overlay-event", listener);
});
} else if (effect.wait && data.videoType === "Local Video") {
let internalDuration = data.videoDuration;
if (internalDuration == null || internalDuration === 0 || internalDuration === "") {
internalDuration = duration;
}
await wait(internalDuration * 1000);
}
return true;
},
Expand Down Expand Up @@ -637,9 +637,6 @@ const playVideo = {
const exitVideo = () => {
delete startedVidCache[this.id]; // eslint-disable-line no-undef
animateVideoExit(`#${wrapperId}`, exitAnimation, exitDuration, inbetweenAnimation);
setTimeout(function(){
sendWebsocketEvent("video-end", {resourceToken: token}); // eslint-disable-line no-undef
}, millisecondsFromString(exitDuration));
};

// Remove div after X time.
Expand Down Expand Up @@ -669,29 +666,6 @@ const playVideo = {

$(".wrapper").append(wrappedHtml);

try {
const url = new URL(youtubeId);
if (url.hostname.includes("www.youtube.com")) {
for (const [key, value] of url.searchParams) {
if (key === "v") {
youtubeId = value;
} else if (key === "t") {
videoStarttime = value;
}
}
}
if (url.hostname.includes("youtu.be")) {
youtubeId = url.pathname.replace("/", "");
for (const [key, value] of url.searchParams) {
if (key === "t") {
videoStarttime = value;
}
}
}
} catch (error) {
//failed to convert url
}

// Add iframe.

const playerVars = {
Expand Down Expand Up @@ -737,9 +711,6 @@ const playVideo = {
onStateChange: (event) => {
if (event.data === 0 && !videoDuration) {
animateVideoExit(`#${wrapperId}`, exitAnimation, exitDuration, inbetweenAnimation);
setTimeout(function(){
sendWebsocketEvent("video-end", {resourceToken: token}); // eslint-disable-line no-undef
}, millisecondsFromString(exitDuration));
}
}
}
Expand All @@ -757,9 +728,6 @@ const playVideo = {
if (videoDuration) {
setTimeout(function () {
animateVideoExit(`#${wrapperId}`, exitAnimation, exitDuration, inbetweenAnimation);
setTimeout(function(){
sendWebsocketEvent("video-end", {resourceToken: token}); // eslint-disable-line no-undef
}, millisecondsFromString(exitDuration));
}, videoDuration);
}
}
Expand Down
26 changes: 13 additions & 13 deletions src/backend/games/builtin/bid/bid-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const bidCommand = {
]
},
onTriggerEvent: async event => {
const { chatEvent, userCommand } = event;
const { chatMessage, userCommand } = event;

const bidSettings = gameManager.getGameSettings("firebot-bid");
const chatter = bidSettings.settings.chatSettings.chatter;
Expand All @@ -113,17 +113,17 @@ const bidCommand = {
const bidAmount = parseInt(triggeredArg);

if (isNaN(bidAmount)) {
await twitchChat.sendChatMessage(`Invalid amount. Please enter a number to start bidding.`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`Invalid amount. Please enter a number to start bidding.`, null, chatter, chatMessage.id);
return;
}

if (activeBiddingInfo.active !== false) {
await twitchChat.sendChatMessage(`There is already a bid running. Use !bid stop to stop it.`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`There is already a bid running. Use !bid stop to stop it.`, null, chatter, chatMessage.id);
return;
}

if (bidAmount < bidSettings.settings.currencySettings.minBid) {
await twitchChat.sendChatMessage(`The opening bid must be more than ${bidSettings.settings.currencySettings.minBid}.`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`The opening bid must be more than ${bidSettings.settings.currencySettings.minBid}.`, null, chatter, chatMessage.id);
return;
}

Expand Down Expand Up @@ -151,53 +151,53 @@ const bidCommand = {
const username = userCommand.commandSender;

if (activeBiddingInfo.active === false) {
await twitchChat.sendChatMessage(`There is no active bidding in progress.`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`There is no active bidding in progress.`, null, chatter, chatMessage.id);
return;
}

const cooldownExpireTime = cooldownCache.get(username);
if (cooldownExpireTime && moment().isBefore(cooldownExpireTime)) {
const timeRemainingDisplay = util.secondsForHumans(Math.abs(moment().diff(cooldownExpireTime, 'seconds')));
await twitchChat.sendChatMessage(`You placed a bid recently! Please wait ${timeRemainingDisplay} before placing another bid.`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`You placed a bid recently! Please wait ${timeRemainingDisplay} before placing another bid.`, null, chatter, chatMessage.id);
return;
}

if (activeBiddingInfo.topBidder === username) {
await twitchChat.sendChatMessage("You are already the top bidder. You can't bid against yourself.", null, chatter, chatEvent.id);
await twitchChat.sendChatMessage("You are already the top bidder. You can't bid against yourself.", null, chatter, chatMessage.id);
return;
}

if (bidAmount < 1) {
await twitchChat.sendChatMessage("Bid amount must be more than 0.", null, chatter, chatEvent.id);
await twitchChat.sendChatMessage("Bid amount must be more than 0.", null, chatter, chatMessage.id);
return;
}

const minBid = bidSettings.settings.currencySettings.minBid;
if (minBid != null & minBid > 0) {
if (bidAmount < minBid) {
await twitchChat.sendChatMessage(`Bid amount must be at least ${minBid} ${currencyName}.`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`Bid amount must be at least ${minBid} ${currencyName}.`, null, chatter, chatMessage.id);
return;
}
}

const userBalance = await currencyDatabase.getUserCurrencyAmount(username, currencyId);
if (userBalance < bidAmount) {
await twitchChat.sendChatMessage(`You don't have enough ${currencyName}!`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`You don't have enough ${currencyName}!`, null, chatter, chatMessage.id);
return;
}

const raiseMinimum = bidSettings.settings.currencySettings.minIncrement;
const minimumBidWithRaise = activeBiddingInfo.currentBid + raiseMinimum;
if (bidAmount < minimumBidWithRaise) {
await twitchChat.sendChatMessage(`You must bid at least ${minimumBidWithRaise} ${currencyName}.`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`You must bid at least ${minimumBidWithRaise} ${currencyName}.`, null, chatter, chatMessage.id);
return;
}

const previousHighBidder = activeBiddingInfo.topBidder;
const previousHighBidAmount = activeBiddingInfo.currentBid;
if (previousHighBidder != null && previousHighBidder !== "") {
await currencyDatabase.adjustCurrencyForUser(previousHighBidder, currencyId, previousHighBidAmount);
await twitchChat.sendChatMessage(`You have been out bid! You've been refunded ${previousHighBidAmount} ${currencyName}.`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`You have been out bid! You've been refunded ${previousHighBidAmount} ${currencyName}.`, null, chatter, chatMessage.id);
}

await currencyDatabase.adjustCurrencyForUser(username, currencyId, -Math.abs(bidAmount));
Expand All @@ -213,7 +213,7 @@ const bidCommand = {
cooldownCache.set(username, expireTime, cooldownSecs);
}
} else {
await twitchChat.sendChatMessage(`Incorrect bid usage: ${userCommand.trigger} [bidAmount]`, null, chatter, chatEvent.id);
await twitchChat.sendChatMessage(`Incorrect bid usage: ${userCommand.trigger} [bidAmount]`, null, chatter, chatMessage.id);
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/backend/games/builtin/heist/heist-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ const heistCommand = {
if (heistSettings.settings.entryMessages.wagerAmountTooHigh) {
const wagerAmountTooHighMsg = heistSettings.settings.entryMessages.wagerAmountTooHigh
.replace("{user}", username)
.replace("minWager}", minWager);
.replace("{maxWager}", maxWager);

await twitchChat.sendChatMessage(wagerAmountTooHighMsg, null, chatter);
}
Expand Down
6 changes: 5 additions & 1 deletion src/backend/variables/builtin-variable-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ exports.loadReplaceVariables = () => {
'array-reverse',
'array-shuffle-raw',
'array-shuffle',
'audio-duration',
'bits-badge-tier',
'bits-badge-unlocked-message',
'bits-cheered',
Expand Down Expand Up @@ -164,6 +165,7 @@ exports.loadReplaceVariables = () => {
'sub-points',
'sub-streak',
'sub-type',
'sub-users',
'target',
'text-capitalize',
'text-contains',
Expand Down Expand Up @@ -203,9 +205,11 @@ exports.loadReplaceVariables = () => {
'username-array-raw',
'username-array',
'username',
'video-duration',
'view-time',
'whisper-message',
'word'
'word',
'youtube-video-duration'
].forEach(filename => {
const definition = require(`./builtin/${filename}`);
replaceVariableManager.registerReplaceVariable(definition);
Expand Down
7 changes: 6 additions & 1 deletion src/backend/variables/builtin/array-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ const model = {
if (jsonArray) {
const array = utils.jsonParse(jsonArray);
if (Array.isArray(array)) {
// Check value for being array or object, otherwise return raw value
if (Array.isArray(array[index]) || Object.prototype.toString.call(array[index]) == "[object Object]")
{
return JSON.stringify(array[index]);
}
return array[index];
}
}
return null;
}
};

module.exports = model;
module.exports = model;
Loading

0 comments on commit 3b54eef

Please sign in to comment.