Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: refactor role management #2427

Merged
merged 18 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/backend/app-management/electron/events/when-ready.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ exports.whenReady = async () => {

windowManagement.updateSplashScreenStatus("Loading custom roles...");
const customRolesManager = require("../../../roles/custom-roles-manager");
customRolesManager.loadCustomRoles();
await customRolesManager.loadCustomRoles();

windowManagement.updateSplashScreenStatus("Loading known bot list...");
const chatRolesManager = require("../../../roles/chat-roles-manager");
Expand Down
6 changes: 3 additions & 3 deletions src/backend/chat/chat-listeners/active-user-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ const ONLINE_TIMEOUT = 450; // 7.50 mins
/**
* Simple User
* @typedef {Object} User
* @property {id} id
* @property {string} id
* @property {string} username
*/

/**
* @typedef {Object} UserDetails
* @property {number} id
* @property {string} id
* @property {string} username
* @property {string} displayName
* @property {string} profilePicUrl
Expand Down Expand Up @@ -156,7 +156,7 @@ async function updateUserOnlineStatus(userDetails, updateDb = false) {

frontendCommunicator.send("twitch:chat:user-joined", {
id: userDetails.id,
username: userDetails.displayName,
username: userDetails.username,
displayName: userDetails.displayName,
roles: roles,
profilePicUrl: userDetails.profilePicUrl,
Expand Down
16 changes: 12 additions & 4 deletions src/backend/chat/chat-listeners/twitch-chat-listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ exports.setupChatListeners = (streamerChatClient, botChatClient) => {
await chatModerationManager.moderateMessage(firebotChatMessage);

if (firebotChatMessage.isVip === true) {
chatRolesManager.addVipToVipList(firebotChatMessage.username);
chatRolesManager.addVipToVipList({
id: msg.userInfo.userId,
username: msg.userInfo.userName,
displayName: msg.userInfo.displayName
});
} else {
chatRolesManager.removeVipFromVipList(firebotChatMessage.username);
chatRolesManager.removeVipFromVipList(msg.userInfo.userId);
}

// send to the frontend
Expand Down Expand Up @@ -126,9 +130,13 @@ exports.setupChatListeners = (streamerChatClient, botChatClient) => {
const firebotChatMessage = await chatHelpers.buildFirebotChatMessage(msg, messageText, false, true);

if (firebotChatMessage.isVip === true) {
chatRolesManager.addVipToVipList(firebotChatMessage.username);
chatRolesManager.addVipToVipList({
id: msg.userInfo.userId,
username: msg.userInfo.userName,
displayName: msg.userInfo.displayName
});
} else {
chatRolesManager.removeVipFromVipList(firebotChatMessage.username);
chatRolesManager.removeVipFromVipList(msg.userInfo.userId);
}

frontendCommunicator.send("twitch:chat:message", firebotChatMessage);
Expand Down
40 changes: 30 additions & 10 deletions src/backend/chat/commands/builtin/custom-role-management.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SystemCommand } from "../../../../types/commands";
import customRoleManager from "../../../roles/custom-roles-manager";
import chat from "../../twitch-chat";
import twitchApi from "../../../twitch-api/api";

/**
* The `!role` command
Expand Down Expand Up @@ -61,37 +62,56 @@ export const CustomRoleManagementSystemCommand: SystemCommand = {

switch (triggeredArg) {
case "add": {
const roleName = args.slice(2);
const roleName = args.slice(2)[0];
const role = customRoleManager.getRoleByName(roleName);
if (role == null) {
await chat.sendChatMessage("Can't find a role by that name.");
} else {
const username = args[1].replace("@", "");
customRoleManager.addViewerToRole(role.id, username);
await chat.sendChatMessage(`Added role ${role.name} to ${username}`);
const user = await twitchApi.users.getUserByName(username);
if (user == null) {
await chat.sendChatMessage(`Could not add role ${role.name} to ${username}. User does not exist.`);
} else {
customRoleManager.addViewerToRole(role.id, {
id: user.id,
username: user.name,
displayName: user.displayName
});
await chat.sendChatMessage(`Added role ${role.name} to ${username}`);
}
}
break;
}
case "remove": {
const roleName = args.slice(2);
const roleName = args.slice(2)[0];
const role = customRoleManager.getRoleByName(roleName);
if (role == null) {
await chat.sendChatMessage("Can't find a role by that name.");
} else {
const username = args[1].replace("@", "");
customRoleManager.removeViewerFromRole(role.id, username);
await chat.sendChatMessage(`Removed role ${role.name} from ${username}`);
const user = await twitchApi.users.getUserByName(username);
if (user == null) {
await chat.sendChatMessage(`Could not remove role ${role.name} from ${username}. User does not exist.`);
} else {
customRoleManager.removeViewerFromRole(role.id, user.id);
await chat.sendChatMessage(`Removed role ${role.name} from ${username}`);
}
}
break;
}
case "list": {
if (args.length > 1) {
const username = args[1].replace("@", "");
const roleNames = customRoleManager.getAllCustomRolesForViewer(username).map((r) => r.name);
if (roleNames.length < 1) {
await chat.sendChatMessage(`${username} has no custom roles assigned.`);
const user = await twitchApi.users.getUserByName(username);
if (user == null) {
await chat.sendChatMessage(`Could not get roles for ${username}. User does not exist.`);
} else {
await chat.sendChatMessage(`${username}'s custom roles: ${roleNames.join(", ")}`);
const roleNames = customRoleManager.getAllCustomRolesForViewer(user.id).map((r) => r.name);
if (roleNames.length < 1) {
await chat.sendChatMessage(`${username} has no custom roles assigned.`);
} else {
await chat.sendChatMessage(`${username}'s custom roles: ${roleNames.join(", ")}`);
}
}

} else {
Expand Down
8 changes: 4 additions & 4 deletions src/backend/chat/moderation/chat-moderation-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ async function moderateMessage(chatMessage) {
return;
}

const userExemptGlobally = rolesManager.userIsInRole(chatMessage.username, chatMessage.roles,
const userExemptGlobally = rolesManager.userIsInRole(chatMessage.userId, chatMessage.roles,
chatModerationSettings.exemptRoles);

if (userExemptGlobally) {
Expand All @@ -184,7 +184,7 @@ async function moderateMessage(chatMessage) {
const twitchApi = require("../../twitch-api/api");
const chat = require("../twitch-chat");

const userExemptForEmoteLimit = rolesManager.userIsInRole(chatMessage.username, chatMessage.roles, chatModerationSettings.emoteLimit.exemptRoles);
const userExemptForEmoteLimit = rolesManager.userIsInRole(chatMessage.userId, chatMessage.roles, chatModerationSettings.emoteLimit.exemptRoles);
if (chatModerationSettings.emoteLimit.enabled && !!chatModerationSettings.emoteLimit.max && !userExemptForEmoteLimit) {
const emoteCount = chatMessage.parts.filter(p => p.type === "emote").length;
const emojiCount = chatMessage.parts
Expand All @@ -203,7 +203,7 @@ async function moderateMessage(chatMessage) {
}
}

const userExemptForUrlModeration = rolesManager.userIsInRole(chatMessage.username, chatMessage.roles, chatModerationSettings.urlModeration.exemptRoles);
const userExemptForUrlModeration = rolesManager.userIsInRole(chatMessage.userId, chatMessage.roles, chatModerationSettings.urlModeration.exemptRoles);
if (chatModerationSettings.urlModeration.enabled && !userExemptForUrlModeration && !permitCommand.hasTemporaryPermission(chatMessage.username)) {
let shouldDeleteMessage = false;
const message = chatMessage.rawText;
Expand Down Expand Up @@ -280,7 +280,7 @@ async function moderateMessage(chatMessage) {
messageId: messageId,
username: username,
scanForBannedWords: chatModerationSettings.bannedWordList.enabled,
isExempt: rolesManager.userIsInRole(chatMessage.username, chatMessage.roles, chatModerationSettings.bannedWordList.exemptRoles),
isExempt: rolesManager.userIsInRole(chatMessage.userId, chatMessage.roles, chatModerationSettings.bannedWordList.exemptRoles),
maxEmotes: null
}
);
Expand Down
8 changes: 6 additions & 2 deletions src/backend/chat/twitch-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,14 @@ frontendCommunicator.onAsync("update-user-vip-status", async (data: UserVipReque

if (shouldBeVip) {
await twitchApi.moderation.addChannelVip(user.id);
chatRolesManager.addVipToVipList(username);
chatRolesManager.addVipToVipList({
id: user.id,
username: user.name,
displayName: user.displayName
});
} else {
await twitchApi.moderation.removeChannelVip(user.id);
chatRolesManager.removeVipFromVipList(username);
chatRolesManager.removeVipFromVipList(user.id);
}
});

Expand Down
14 changes: 9 additions & 5 deletions src/backend/chat/twitch-commands/moderation-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,19 @@ export const vipHandler: TwitchSlashCommandHandler<[string]> = {
};
},
handle: async ([targetUsername]) => {
const targetUserId = (await twitchApi.users.getUserByName(targetUsername))?.id;
const targetUser = await twitchApi.users.getUserByName(targetUsername);

if (targetUserId == null) {
if (targetUser == null) {
return false;
}

const result = await twitchApi.moderation.addChannelVip(targetUserId);
const result = await twitchApi.moderation.addChannelVip(targetUser.id);
if (result === true) {
chatRolesManager.addVipToVipList(targetUsername);
chatRolesManager.addVipToVipList({
id: targetUser.id,
username: targetUser.name,
displayName: targetUser.displayName
});
}
return result;
}
Expand Down Expand Up @@ -155,7 +159,7 @@ export const unvipHandler: TwitchSlashCommandHandler<[string]> = {

const result = await twitchApi.moderation.removeChannelVip(targetUserId);
if (result === true) {
chatRolesManager.removeVipFromVipList(targetUsername);
chatRolesManager.removeVipFromVipList(targetUserId);
}
return result;
}
Expand Down
20 changes: 15 additions & 5 deletions src/backend/common/profile-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,14 @@ function deleteProfile() {
}

const getPathInProfile = function(filepath) {
const profilePath =
`${dataAccess.getUserDataPath()}/profiles/${getLoggedInProfile()}`;
return path.join(profilePath, filepath);
return path.join(dataAccess.getUserDataPath(),
"profiles",
getLoggedInProfile(),
filepath);
};

const getPathInProfileRelativeToUserData = function(filepath) {
return path.join("profiles", getLoggedInProfile(), filepath);
};

/**
Expand All @@ -178,11 +183,15 @@ const getJsonDbInProfile = function(filepath, humanReadable = true) {
};

const profileDataPathExistsSync = function(filePath) {
const profilePath = `/profiles/${getLoggedInProfile()}`,
joinedPath = path.join(profilePath, filePath);
const joinedPath = getPathInProfileRelativeToUserData(filePath);
return dataAccess.userDataPathExistsSync(joinedPath);
};

const deletePathInProfile = function(filePath) {
const joinedPath = getPathInProfileRelativeToUserData(filePath);
return dataAccess.deletePathInUserData(joinedPath);
};

exports.getLoggedInProfile = getLoggedInProfile;
exports.createNewProfile = createNewProfile;
exports.getPathInProfile = getPathInProfile;
Expand All @@ -193,3 +202,4 @@ exports.logInProfile = logInProfile;
exports.renameProfile = renameProfile;
exports.getNewProfileName = () => profileToRename;
exports.hasProfileRename = () => profileToRename != null;
exports.deletePathInProfile = deletePathInProfile;
10 changes: 5 additions & 5 deletions src/backend/currency/currency-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,8 @@ class CurrencyManager {

const teamRoles: Record<string, Array<{ id: string; name: string; }>> = {};
for (const viewer of onlineViewers) {
teamRoles[viewer.username] = await teamRolesManager
.getAllTeamRolesForViewer(viewer.username);
teamRoles[viewer._id] = await teamRolesManager
.getAllTeamRolesForViewer(viewer._id);
}

const userIdsInRoles = onlineViewers
Expand All @@ -390,9 +390,9 @@ class CurrencyManager {

const allRoles = [
...twitchRoles.map(tr => twitchRolesManager.mapTwitchRole(tr)),
...customRolesManager.getAllCustomRolesForViewer(u.username),
...teamRoles[u.username],
...firebotRolesManager.getAllFirebotRolesForViewer(u.username)
...customRolesManager.getAllCustomRolesForViewer(u._id),
...teamRoles[u._id],
...firebotRolesManager.getAllFirebotRolesForViewer(u._id)
];

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict";

const { viewerHasRoles } = require("../../../../../roles/role-helpers");
const twitchApi = require("../../../../../twitch-api/api");
const roleHelpers = require("../../../../../roles/role-helpers").default;

module.exports = {
id: "firebot:viewerroles",
Expand All @@ -10,7 +11,7 @@ module.exports = {
leftSideValueType: "text",
leftSideTextPlaceholder: "Enter username",
rightSideValueType: "preset",
getRightSidePresetValues: viewerRolesService => {
getRightSidePresetValues: (viewerRolesService) => {
return viewerRolesService.getAllRoles()
.map(r => ({
value: r.id,
Expand Down Expand Up @@ -42,7 +43,12 @@ module.exports = {
username = trigger.metadata.username;
}

const hasRole = await viewerHasRoles(username, [rightSideValue]);
const user = await twitchApi.users.getUserByName(username);
if (user == null) {
return false;
}

const hasRole = await roleHelpers.viewerHasRoles(user.id, [rightSideValue]);

switch (comparisonType) {
case "include":
Expand Down
25 changes: 19 additions & 6 deletions src/backend/effects/builtin/update-role.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"use strict";

const { EffectCategory } = require('../../../shared/effect-constants');
const twitchApi = require("../../twitch-api/api");
const customRolesManager = require("../../roles/custom-roles-manager");
const logger = require('../../logwrapper');

/**
* The Delay effect
Expand Down Expand Up @@ -111,6 +113,11 @@ const delay = {
*/
onTriggerEvent: async event => {
const effect = event.effect;

if (effect.removeAllRoleId) {
customRolesManager.removeAllViewersFromRole(effect.removeAllRoleId);
return;
}

let username = "";
if (effect.viewerType === "current") {
Expand All @@ -119,16 +126,22 @@ const delay = {
username = effect.customViewer ? effect.customViewer.trim() : "";
}

if (effect.addRoleId) {
customRolesManager.addViewerToRole(effect.addRoleId, username);
const user = await twitchApi.users.getUserByName(username);
if (user == null) {
logger.warn(`Unable to ${effect.addRoleId ? "add" : "remove"} custom role for ${username}. User does not exist.`);
return;
}

if (effect.removeRoleId) {
customRolesManager.removeViewerFromRole(effect.removeRoleId, username);
if (effect.addRoleId) {
customRolesManager.addViewerToRole(effect.addRoleId, {
id: user.id,
username: user.name,
displayName: user.displayName
});
}

if (effect.removeAllRoleId) {
customRolesManager.removeAllViewersFromRole(effect.removeAllRoleId);
if (effect.removeRoleId) {
customRolesManager.removeViewerFromRole(effect.removeRoleId, user.id);
}

return true;
Expand Down
Loading
Loading