vantiv.io 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +864 -0
- package/index.js +13 -0
- package/package.json +28 -0
- package/src/classes/Actions/Awaiter.js +202 -0
- package/src/classes/Actions/Channel.js +73 -0
- package/src/classes/Actions/Direct.js +263 -0
- package/src/classes/Actions/Inventory.js +156 -0
- package/src/classes/Actions/Music.js +278 -0
- package/src/classes/Actions/Player.js +377 -0
- package/src/classes/Actions/Public.js +66 -0
- package/src/classes/Actions/Room.js +333 -0
- package/src/classes/Actions/Utils.js +29 -0
- package/src/classes/Actions/lib/AudioStreaming.js +447 -0
- package/src/classes/Caches/MovementCache.js +357 -0
- package/src/classes/Handlers/AxiosErrorHandler.js +68 -0
- package/src/classes/Handlers/ErrorHandler.js +65 -0
- package/src/classes/Handlers/EventHandlers.js +259 -0
- package/src/classes/Handlers/WebSocketHandlers.js +54 -0
- package/src/classes/Managers/ChannelManager.js +303 -0
- package/src/classes/Managers/DanceFloorManagers.js +509 -0
- package/src/classes/Managers/Helpers/CleanupManager.js +130 -0
- package/src/classes/Managers/Helpers/LoggerManager.js +171 -0
- package/src/classes/Managers/Helpers/MetricsManager.js +83 -0
- package/src/classes/Managers/Networking/ConnectionManager.js +259 -0
- package/src/classes/Managers/Networking/CooldownManager.js +516 -0
- package/src/classes/Managers/Networking/EventsManager.js +64 -0
- package/src/classes/Managers/Networking/KeepAliveManager.js +109 -0
- package/src/classes/Managers/Networking/MessageHandler.js +110 -0
- package/src/classes/Managers/Networking/Request.js +329 -0
- package/src/classes/Managers/PermissionManager.js +288 -0
- package/src/classes/WebApi/Category/Grab.js +98 -0
- package/src/classes/WebApi/Category/Item.js +347 -0
- package/src/classes/WebApi/Category/Post.js +154 -0
- package/src/classes/WebApi/Category/Room.js +137 -0
- package/src/classes/WebApi/Category/User.js +88 -0
- package/src/classes/WebApi/webapi.js +52 -0
- package/src/constants/TypesConstants.js +89 -0
- package/src/constants/WebSocketConstants.js +80 -0
- package/src/core/Highrise.js +123 -0
- package/src/core/HighriseWebsocket.js +228 -0
- package/src/utils/ConvertSvgToPng.js +51 -0
- package/src/utils/ModelPool.js +160 -0
- package/src/utils/Models.js +128 -0
- package/src/utils/versionCheck.js +27 -0
- package/src/validators/ConfigValidator.js +205 -0
- package/src/validators/ConnectionValidator.js +65 -0
- package/typings/index.d.ts +3820 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
const fs = require('fs').promises;
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
class PermissionManager {
|
|
5
|
+
constructor(bot, utils, options = {}) {
|
|
6
|
+
this.bot = bot;
|
|
7
|
+
this.logger = utils?.logger || console;
|
|
8
|
+
|
|
9
|
+
this.config = {
|
|
10
|
+
dataDir: options.dataDir || './data',
|
|
11
|
+
filename: options.filename || 'permissions.json',
|
|
12
|
+
webapiSyncInterval: options.webapiSyncInterval || 300000,
|
|
13
|
+
fileSaveInterval: options.fileSaveInterval || 180000,
|
|
14
|
+
autoLoad: options.autoLoad !== false,
|
|
15
|
+
customRoles: options.customRoles || [],
|
|
16
|
+
...options
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
this.roles = new Map();
|
|
20
|
+
this.webapiModerators = new Set();
|
|
21
|
+
this.webapiDesigners = new Set();
|
|
22
|
+
|
|
23
|
+
this.initialized = false;
|
|
24
|
+
this.syncInProgress = false;
|
|
25
|
+
this.saveQueued = false;
|
|
26
|
+
|
|
27
|
+
if (this.config.autoLoad) {
|
|
28
|
+
this._initialize();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async _initialize() {
|
|
33
|
+
try {
|
|
34
|
+
await fs.mkdir(this.config.dataDir, { recursive: true });
|
|
35
|
+
await this.loadFromFile();
|
|
36
|
+
this._createCustomRoles();
|
|
37
|
+
this._startWebApiSync();
|
|
38
|
+
this._startAutoSave();
|
|
39
|
+
this.initialized = true;
|
|
40
|
+
this.logger.success('PermissionManager', '✅ Ready! Auto-syncing every 5 minutes.');
|
|
41
|
+
} catch (error) {
|
|
42
|
+
this.logger.error('PermissionManager', 'Setup failed', error);
|
|
43
|
+
this._createCustomRoles();
|
|
44
|
+
this.initialized = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
_createCustomRoles() {
|
|
49
|
+
if (this.config.customRoles && Array.isArray(this.config.customRoles)) {
|
|
50
|
+
for (const roleName of this.config.customRoles) {
|
|
51
|
+
if (!this.roles.has(roleName)) {
|
|
52
|
+
this.roles.set(roleName, new Set());
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async syncWithWebApi() {
|
|
59
|
+
if (this.syncInProgress) return false;
|
|
60
|
+
this.syncInProgress = true;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const currentRoom = await this.bot.webapi.room.getCurrentRoom();
|
|
64
|
+
if (!currentRoom) return false;
|
|
65
|
+
|
|
66
|
+
const oldModerators = new Set(this.webapiModerators);
|
|
67
|
+
const oldDesigners = new Set(this.webapiDesigners);
|
|
68
|
+
|
|
69
|
+
this.webapiModerators = new Set(currentRoom.moderatorIds || []);
|
|
70
|
+
this.webapiDesigners = new Set(currentRoom.designerIds || []);
|
|
71
|
+
|
|
72
|
+
if (!this.roles.has('moderator')) this.roles.set('moderator', new Set());
|
|
73
|
+
if (!this.roles.has('designer')) this.roles.set('designer', new Set());
|
|
74
|
+
|
|
75
|
+
const moderatorRole = this.roles.get('moderator');
|
|
76
|
+
const designerRole = this.roles.get('designer');
|
|
77
|
+
|
|
78
|
+
for (const modId of this.webapiModerators) moderatorRole.add(modId);
|
|
79
|
+
for (const designerId of this.webapiDesigners) designerRole.add(designerId);
|
|
80
|
+
|
|
81
|
+
const newMods = Array.from(this.webapiModerators).filter(id => !oldModerators.has(id));
|
|
82
|
+
const removedMods = Array.from(oldModerators).filter(id => !this.webapiModerators.has(id));
|
|
83
|
+
|
|
84
|
+
if (newMods.length > 0 || removedMods.length > 0) {
|
|
85
|
+
this.logger.info('PermissionManager', `Web API sync: +${newMods.length} -${removedMods.length} moderators`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this.queueSave();
|
|
89
|
+
return true;
|
|
90
|
+
|
|
91
|
+
} catch (error) {
|
|
92
|
+
this.logger.error('PermissionManager', `Web API sync failed ${error.message}`, error);
|
|
93
|
+
return false;
|
|
94
|
+
} finally {
|
|
95
|
+
this.syncInProgress = false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
_startWebApiSync() {
|
|
100
|
+
setTimeout(() => this.syncWithWebApi(), 5000);
|
|
101
|
+
setInterval(() => this.syncWithWebApi(), this.config.webapiSyncInterval);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
createRole(roleName) {
|
|
105
|
+
if (this.roles.has(roleName)) return false;
|
|
106
|
+
this.roles.set(roleName, new Set());
|
|
107
|
+
this.queueSave();
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
addToRole(roleName, userId) {
|
|
112
|
+
if (!this.roles.has(roleName)) this.createRole(roleName);
|
|
113
|
+
const added = this.roles.get(roleName).add(userId);
|
|
114
|
+
if (added) this.queueSave();
|
|
115
|
+
return added;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
removeFromRole(roleName, userId) {
|
|
119
|
+
if (!this.roles.has(roleName)) return false;
|
|
120
|
+
const removed = this.roles.get(roleName).delete(userId);
|
|
121
|
+
if (removed) this.queueSave();
|
|
122
|
+
return removed;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
hasRole(roleName, userId) {
|
|
126
|
+
if (!this.roles.has(roleName)) return false;
|
|
127
|
+
return this.roles.get(roleName).has(userId);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
hasAnyRole(roleNames, userId) {
|
|
131
|
+
for (const roleName of roleNames) {
|
|
132
|
+
if (this.hasRole(roleName, userId)) return true;
|
|
133
|
+
}
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
getUserRoles(userId) {
|
|
138
|
+
const userRoles = [];
|
|
139
|
+
for (const [roleName, userSet] of this.roles) {
|
|
140
|
+
if (userSet.has(userId)) userRoles.push(roleName);
|
|
141
|
+
}
|
|
142
|
+
return userRoles;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
getUsersInRole(roleName) {
|
|
146
|
+
if (!this.roles.has(roleName)) return [];
|
|
147
|
+
return Array.from(this.roles.get(roleName));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
getAllRoles() {
|
|
151
|
+
return Array.from(this.roles.keys());
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
deleteRole(roleName) {
|
|
155
|
+
const deleted = this.roles.delete(roleName);
|
|
156
|
+
if (deleted) this.queueSave();
|
|
157
|
+
return deleted;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
renameRole(oldName, newName) {
|
|
161
|
+
if (!this.roles.has(oldName) || this.roles.has(newName)) return false;
|
|
162
|
+
const userSet = this.roles.get(oldName);
|
|
163
|
+
this.roles.set(newName, userSet);
|
|
164
|
+
this.roles.delete(oldName);
|
|
165
|
+
this.queueSave();
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async loadFromFile() {
|
|
170
|
+
try {
|
|
171
|
+
const filePath = path.join(this.config.dataDir, this.config.filename);
|
|
172
|
+
try { await fs.access(filePath); } catch { return false; }
|
|
173
|
+
|
|
174
|
+
const data = await fs.readFile(filePath, 'utf8');
|
|
175
|
+
const saved = JSON.parse(data);
|
|
176
|
+
|
|
177
|
+
for (const [roleName, userIds] of Object.entries(saved)) {
|
|
178
|
+
if (roleName !== '_meta') this.roles.set(roleName, new Set(userIds));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
this.logger.success('PermissionManager', `Loaded ${this.roles.size} roles from file`);
|
|
182
|
+
return true;
|
|
183
|
+
|
|
184
|
+
} catch (error) {
|
|
185
|
+
this.logger.error('PermissionManager', 'Failed to load roles', error);
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async saveToFile() {
|
|
191
|
+
if (this.saveQueued) return;
|
|
192
|
+
this.saveQueued = true;
|
|
193
|
+
|
|
194
|
+
setTimeout(async () => {
|
|
195
|
+
try {
|
|
196
|
+
const filePath = path.join(this.config.dataDir, this.config.filename);
|
|
197
|
+
const tempPath = filePath + '.tmp';
|
|
198
|
+
|
|
199
|
+
const data = {};
|
|
200
|
+
for (const [roleName, userSet] of this.roles) {
|
|
201
|
+
data[roleName] = Array.from(userSet);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
data._meta = {
|
|
205
|
+
savedAt: new Date().toISOString(),
|
|
206
|
+
totalRoles: this.roles.size,
|
|
207
|
+
totalUsers: Array.from(this.roles.values()).reduce((sum, set) => sum + set.size, 0)
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
await fs.writeFile(tempPath, JSON.stringify(data, null, 2), 'utf8');
|
|
211
|
+
await fs.rename(tempPath, filePath);
|
|
212
|
+
|
|
213
|
+
} catch (error) {
|
|
214
|
+
this.logger.error('PermissionManager', 'Failed to save roles', error);
|
|
215
|
+
} finally {
|
|
216
|
+
this.saveQueued = false;
|
|
217
|
+
}
|
|
218
|
+
}, 1000);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
queueSave() {
|
|
222
|
+
if (!this.saveQueued) this.saveToFile();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
_startAutoSave() {
|
|
226
|
+
setInterval(() => this.queueSave(), this.config.fileSaveInterval);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
isOwner(userId) {
|
|
230
|
+
return this.hasRole('owner', userId);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
isModerator(userId) {
|
|
234
|
+
return this.hasRole('moderator', userId) || this.webapiModerators.has(userId);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
isDesigner(userId) {
|
|
238
|
+
return this.hasRole('designer', userId) || this.webapiDesigners.has(userId);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
getAllModerators() {
|
|
242
|
+
const moderators = new Set();
|
|
243
|
+
if (this.roles.has('moderator')) {
|
|
244
|
+
for (const userId of this.roles.get('moderator')) moderators.add(userId);
|
|
245
|
+
}
|
|
246
|
+
for (const userId of this.webapiModerators) moderators.add(userId);
|
|
247
|
+
return Array.from(moderators);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
getAllDesigners() {
|
|
251
|
+
const designers = new Set();
|
|
252
|
+
if (this.roles.has('designer')) {
|
|
253
|
+
for (const userId of this.roles.get('designer')) designers.add(userId);
|
|
254
|
+
}
|
|
255
|
+
for (const userId of this.webapiDesigners) designers.add(userId);
|
|
256
|
+
return Array.from(designers);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async forceSync() {
|
|
260
|
+
await this.syncWithWebApi();
|
|
261
|
+
await this.saveToFile();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
exportToObject() {
|
|
265
|
+
const obj = {};
|
|
266
|
+
for (const [roleName, userSet] of this.roles) {
|
|
267
|
+
obj[roleName] = Array.from(userSet);
|
|
268
|
+
}
|
|
269
|
+
return obj;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
importFromObject(obj) {
|
|
273
|
+
for (const [roleName, userIds] of Object.entries(obj)) {
|
|
274
|
+
if (Array.isArray(userIds)) this.roles.set(roleName, new Set(userIds));
|
|
275
|
+
}
|
|
276
|
+
this.queueSave();
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
clearAll() {
|
|
281
|
+
this.queueSave();
|
|
282
|
+
this.roles.clear();
|
|
283
|
+
this.webapiModerators.clear();
|
|
284
|
+
this.webapiDesigners.clear();
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
module.exports = PermissionManager;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
|
|
2
|
+
class GrabCategory {
|
|
3
|
+
constructor(webapi, AxiosError) {
|
|
4
|
+
this.webapi = webapi;
|
|
5
|
+
this.logger = webapi.logger;
|
|
6
|
+
this.base = webapi.base;
|
|
7
|
+
this.AxiosErrorHandler = AxiosError
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async get(grabId) {
|
|
11
|
+
const method = 'bot.webapi.grab.get'
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
if (!grabId || typeof grabId !== 'string') {
|
|
15
|
+
throw new TypeError('grabId must be a non-empty string');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const response = await this.base.get(`/grabs/${grabId}`);
|
|
19
|
+
if (response.status === 200 && response.data?.grab) {
|
|
20
|
+
return this._formatGrab(response.data.grab);
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
if (error instanceof TypeError) {
|
|
25
|
+
this.logger.error(method, `TypeError: ${error.message}`, { grabId }, error);
|
|
26
|
+
} else {
|
|
27
|
+
return this.AxiosErrorHandler.handle(error, this.logger, method, { grabId });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
_formatGrab(grabData) {
|
|
33
|
+
return {
|
|
34
|
+
id: grabData.grab_id,
|
|
35
|
+
title: grabData.title,
|
|
36
|
+
description: grabData.description,
|
|
37
|
+
bannerImgUrl: grabData.banner_img_url,
|
|
38
|
+
startsAt: grabData.starts_at,
|
|
39
|
+
expiresAt: grabData.expires_at,
|
|
40
|
+
rewards: Array.isArray(grabData.rewards) ? grabData.rewards.map(reward => this._formatGrabReward(reward)) : [],
|
|
41
|
+
costs: Array.isArray(grabData.costs) ? grabData.costs.map(cost => this._formatGrabCost(cost)) : [],
|
|
42
|
+
kompuRewards: Array.isArray(grabData.kompu_rewards) ? grabData.kompu_rewards.map(reward => this._formatGrabReward(reward)) : [],
|
|
43
|
+
limitedTimeKompu: grabData.limited_time_kompu ? this._formatLimitedKompu(grabData.limited_time_kompu) : null,
|
|
44
|
+
progressReward: grabData.progress_reward ? this._formatProgressReward(grabData.progress_reward) : null
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
_formatGrabReward(reward) {
|
|
49
|
+
return {
|
|
50
|
+
amount: reward.amount,
|
|
51
|
+
rewardId: reward.reward_id,
|
|
52
|
+
itemId: reward.item_id,
|
|
53
|
+
accountBound: reward.account_bound || false,
|
|
54
|
+
metadata: reward.metadata,
|
|
55
|
+
nfiMetadata: reward.nfi_metadata,
|
|
56
|
+
itemNumber: reward.item_number,
|
|
57
|
+
stackId: reward.stack_id,
|
|
58
|
+
nfiTemplateMetadata: reward.nfi_template_metadata,
|
|
59
|
+
totalAmount: reward.total_amount,
|
|
60
|
+
bannerItem: reward.banner_item || false,
|
|
61
|
+
primaryImgUrl: reward.primary_img_url,
|
|
62
|
+
secondaryImgUrl: reward.secondary_img_url,
|
|
63
|
+
isTradable: reward.is_tradable || false
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
_formatGrabCost(cost) {
|
|
68
|
+
return {
|
|
69
|
+
amount: cost.amount,
|
|
70
|
+
rewardId: cost.reward_id,
|
|
71
|
+
itemId: cost.item_id,
|
|
72
|
+
accountBound: cost.account_bound || false,
|
|
73
|
+
metadata: cost.metadata,
|
|
74
|
+
nfiMetadata: cost.nfi_metadata,
|
|
75
|
+
itemNumber: cost.item_number,
|
|
76
|
+
stackId: cost.stack_id,
|
|
77
|
+
nfiTemplateMetadata: cost.nfi_template_metadata,
|
|
78
|
+
totalAmount: cost.total_amount,
|
|
79
|
+
bannerItem: cost.banner_item || false
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
_formatLimitedKompu(limitedKompu) {
|
|
84
|
+
return {
|
|
85
|
+
expiresAt: limitedKompu.expires_at,
|
|
86
|
+
rewards: Array.isArray(limitedKompu.rewards) ? limitedKompu.rewards.map(reward => this._formatGrabReward(reward)) : []
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
_formatProgressReward(progressReward) {
|
|
91
|
+
return {
|
|
92
|
+
rewardsAt: progressReward.rewards_at,
|
|
93
|
+
rewards: Array.isArray(progressReward.rewards) ? progressReward.rewards.map(reward => this._formatGrabReward(reward)) : []
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = GrabCategory
|