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,156 @@
|
|
|
1
|
+
const { payment_methods, default_skin } = require("highrise-core/src/constants/TypesConstants");
|
|
2
|
+
|
|
3
|
+
class InventoryClass {
|
|
4
|
+
constructor(bot) {
|
|
5
|
+
this.bot = bot;
|
|
6
|
+
this.logger = this.bot.logger
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async get() {
|
|
10
|
+
const method = 'bot.inventory.get'
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const payload = {
|
|
14
|
+
_type: 'GetInventoryRequest'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const response = await this.bot._requestResponse.send(payload)
|
|
18
|
+
return response.items
|
|
19
|
+
} catch (error) {
|
|
20
|
+
this.logger.error(method, `Failed to get bot inventory: ${error.message}`, error);
|
|
21
|
+
return []
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
outfit = {
|
|
26
|
+
set: async (outfit = default_skin) => {
|
|
27
|
+
const method = 'bot.inventory.outfit.set'
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
if (!outfit || !Array.isArray(outfit)) throw new TypeError('outfit must be an array')
|
|
31
|
+
|
|
32
|
+
const payload = {
|
|
33
|
+
_type: 'SetOutfitRequest',
|
|
34
|
+
outfit: outfit
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const response = await this.bot._fireAndForget.send(payload)
|
|
38
|
+
return response.success;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
if (error instanceof TypeError) {
|
|
41
|
+
this.logger.error(method, `TypeError: ${error.message}`, error);
|
|
42
|
+
} else {
|
|
43
|
+
this.logger.error(method, `Failed to set outfit: ${error.message}`, error);
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
wallet = {
|
|
51
|
+
get: async () => {
|
|
52
|
+
const method = 'bot.inventory.wallet.get'
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const payload = {
|
|
56
|
+
_type: 'GetWalletRequest'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const response = await this.bot._requestResponse.send(payload)
|
|
60
|
+
|
|
61
|
+
const walletData = response.content.reduce((acc, item) => {
|
|
62
|
+
acc[item.type] = item.amount;
|
|
63
|
+
return acc;
|
|
64
|
+
}, {});
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
gold: walletData.gold || 0,
|
|
68
|
+
boost_tokens: walletData.room_boost_tokens || 0,
|
|
69
|
+
voice_tokens: walletData.room_voice_tokens || 0,
|
|
70
|
+
};
|
|
71
|
+
} catch (error) {
|
|
72
|
+
this.logger.error(method, `Failed to get bot wallet: ${error.message}`, error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
boost = {
|
|
78
|
+
buy: async (payment_method = 'bot_wallet_only', amount = 1) => {
|
|
79
|
+
const method = 'bot.inventory.boost.buy'
|
|
80
|
+
try {
|
|
81
|
+
if (!payment_method || typeof payment_method !== 'string' || !payment_methods.includes(payment_method)) {
|
|
82
|
+
throw new TypeError(`payment_method must be a string and a vaild payment method`)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!amount || typeof amount !== 'number' || amount <= 0) throw new TypeError('amount must be a positive number')
|
|
86
|
+
|
|
87
|
+
const payload = {
|
|
88
|
+
_type: 'BuyRoomBoostRequest',
|
|
89
|
+
payment_method: payment_method,
|
|
90
|
+
amount: amount
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const response = await this.bot._requestResponse.send(payload)
|
|
94
|
+
return response.result
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (error instanceof TypeError) {
|
|
97
|
+
this.logger.error(method, `TypeError: ${error.message}`, { payment_method, amount }, error);
|
|
98
|
+
} else {
|
|
99
|
+
this.logger.error(method, `Failed to buy boost token: ${error.message}`, { payment_method, amount }, error);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
voice = {
|
|
106
|
+
buy: async (payment_method = 'bot_wallet_only') => {
|
|
107
|
+
const method = 'bot.inventory.voice.buy'
|
|
108
|
+
try {
|
|
109
|
+
if (!payment_method || typeof payment_method !== 'string' || !payment_methods.includes(payment_method)) {
|
|
110
|
+
throw new TypeError(`payment_method must be a string and a vaild payment method\nValid payment methods: ${payment_methods.join(', ')}`)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const payload = {
|
|
114
|
+
_type: 'BuyVoiceTimeRequest',
|
|
115
|
+
payment_method: payment_method
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const response = await this.bot._requestResponse.send(payload)
|
|
119
|
+
return response.result
|
|
120
|
+
} catch (error) {
|
|
121
|
+
if (error instanceof TypeError) {
|
|
122
|
+
this.logger.error(method, `TypeError: ${error.message}`, { payment_method }, error);
|
|
123
|
+
} else {
|
|
124
|
+
this.logger.error(method, `Failed to buy voice token: ${error.message}`, { payment_method }, error);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
item = {
|
|
131
|
+
buy: async (item_id) => {
|
|
132
|
+
const method = 'bot.inventory.item.buy'
|
|
133
|
+
try {
|
|
134
|
+
if (!item_id || typeof item_id !== 'string') {
|
|
135
|
+
throw new TypeError(`item_id must be a string`)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const payload = {
|
|
139
|
+
_type: 'BuyItemRequest',
|
|
140
|
+
item_id: item_id
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const response = await this.bot._requestResponse.send(payload)
|
|
144
|
+
return response.result
|
|
145
|
+
} catch (error) {
|
|
146
|
+
if (error instanceof TypeError) {
|
|
147
|
+
this.logger.error(method, `TypeError: ${error.message}`, { item_id }, error);
|
|
148
|
+
} else {
|
|
149
|
+
this.logger.error(method, `Failed to buy item: ${error.message}`, { item_id }, error);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
module.exports = { InventoryClass }
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
const { IcecastStreamer, IcecastQueue, Track, YouTubeExtractor, IcecastServer } = require('./lib/AudioStreaming.js');
|
|
2
|
+
const EventEmitter = require('events')
|
|
3
|
+
|
|
4
|
+
class MusicClass extends EventEmitter {
|
|
5
|
+
constructor(bot, config = {}) {
|
|
6
|
+
super()
|
|
7
|
+
this.bot = bot;
|
|
8
|
+
this.config = {
|
|
9
|
+
enabled: config.enabled || false,
|
|
10
|
+
icecast: config.icecast || {},
|
|
11
|
+
queue: config.queue || {},
|
|
12
|
+
autoStartServer: config.autoStartServer || true,
|
|
13
|
+
serverPort: config.serverPort || 3000,
|
|
14
|
+
maxQueueSize: config.maxQueueSize || 100,
|
|
15
|
+
defaultVolume: config.defaultVolume || 80,
|
|
16
|
+
allowedFormats: config.allowedFormats || ['youtube', 'direct']
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
if (!this.config.enabled) {
|
|
20
|
+
console.log('Music module is disabled. Enable it in config to use music features.');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
this.initializeStreamer();
|
|
25
|
+
this.setupEventHandlers();
|
|
26
|
+
|
|
27
|
+
if (this.config.autoStartServer) {
|
|
28
|
+
this.startWebServer();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
initializeStreamer() {
|
|
34
|
+
try {
|
|
35
|
+
this.streamer = new IcecastStreamer(this.config.icecast);
|
|
36
|
+
this.queue = new IcecastQueue(this.streamer, this.config.queue);
|
|
37
|
+
|
|
38
|
+
this.streamer.on('playbackStart', (track) => {
|
|
39
|
+
this.emit('playbackStart', track);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
this.streamer.on('playbackEnd', (track) => {
|
|
43
|
+
this.emit('playbackEnd', track);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.streamer.on('progress', (data) => {
|
|
47
|
+
this.emit('progress', data);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
this.streamer.on('error', (error) => {
|
|
51
|
+
this.emit('error', error);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
this.streamer.on('streamStopped', () => {
|
|
55
|
+
this.emit('streamStopped');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error('Failed to initialize Icecast streamer:', error);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
setupEventHandlers() {
|
|
65
|
+
this.bot.on('Ready', () => {
|
|
66
|
+
this.emit('Ready');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
this.bot.on('error', (error) => {
|
|
70
|
+
this.emit('error', error);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async play(query, metadata = {}) {
|
|
75
|
+
try {
|
|
76
|
+
if (!this.streamer) {
|
|
77
|
+
throw new Error('Streamer not initialized');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let trackInfo;
|
|
81
|
+
let source = 'direct';
|
|
82
|
+
|
|
83
|
+
if (this.isValidUrl(query)) {
|
|
84
|
+
if (query.includes('youtube.com') || query.includes('youtu.be')) {
|
|
85
|
+
trackInfo = await YouTubeExtractor.getStreamUrl(query);
|
|
86
|
+
source = 'youtube';
|
|
87
|
+
} else {
|
|
88
|
+
trackInfo = {
|
|
89
|
+
url: query,
|
|
90
|
+
title: metadata.title || 'Unknown Track',
|
|
91
|
+
duration: metadata.duration || 0,
|
|
92
|
+
thumbnail: metadata.thumbnail || null
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
trackInfo = await YouTubeExtractor.searchTrack(query);
|
|
97
|
+
source = 'youtube';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!trackInfo) {
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
error: 'Could not find or play the requested track'
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const track = new Track({
|
|
108
|
+
url: trackInfo.url,
|
|
109
|
+
title: trackInfo.title || metadata.title || 'Unknown Track',
|
|
110
|
+
duration: trackInfo.duration || metadata.duration || 0,
|
|
111
|
+
requester: metadata.requester || 'System',
|
|
112
|
+
requesterId: metadata.requesterId || 'system',
|
|
113
|
+
thumbnail: trackInfo.thumbnail || metadata.thumbnail,
|
|
114
|
+
source: source
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const result = await this.queue.add(track);
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
success: true,
|
|
121
|
+
track: {
|
|
122
|
+
title: track.title,
|
|
123
|
+
duration: track.duration,
|
|
124
|
+
formattedDuration: track.getFormattedDuration(),
|
|
125
|
+
requester: track.requester,
|
|
126
|
+
thumbnail: track.thumbnail
|
|
127
|
+
},
|
|
128
|
+
position: result.position,
|
|
129
|
+
isNowPlaying: result.isNowPlaying || false
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error('Error playing track:', error);
|
|
134
|
+
return {
|
|
135
|
+
success: false,
|
|
136
|
+
error: error.message
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async skip() {
|
|
142
|
+
try {
|
|
143
|
+
const result = await this.queue.skip();
|
|
144
|
+
|
|
145
|
+
let upcoming = null;
|
|
146
|
+
if (this.queue.queue.length > 0) {
|
|
147
|
+
const nextTrack = this.queue.queue[0];
|
|
148
|
+
upcoming = {
|
|
149
|
+
title: nextTrack.title,
|
|
150
|
+
duration: nextTrack.duration,
|
|
151
|
+
formattedDuration: nextTrack.getFormattedDuration()
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
success: result,
|
|
157
|
+
upcoming: upcoming
|
|
158
|
+
};
|
|
159
|
+
} catch (error) {
|
|
160
|
+
console.error('Error skipping track:', error);
|
|
161
|
+
return {
|
|
162
|
+
success: false,
|
|
163
|
+
error: error.message
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
getNowPlaying() {
|
|
169
|
+
const np = this.streamer.getNowPlaying();
|
|
170
|
+
if (!np || !np.track) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
track: np.track,
|
|
176
|
+
position: np.position || 0,
|
|
177
|
+
duration: np.duration || 0,
|
|
178
|
+
progress: np.progress || 0,
|
|
179
|
+
remaining: np.remaining || 0,
|
|
180
|
+
formattedPosition: this.formatDuration(np.position || 0),
|
|
181
|
+
formattedDuration: np.track.getFormattedDuration(),
|
|
182
|
+
formattedRemaining: this.formatDuration(np.remaining || 0)
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
getQueue() {
|
|
187
|
+
return {
|
|
188
|
+
queue: this.queue?.getQueue(),
|
|
189
|
+
upcoming: this.queue?.getQueue().slice(0, 10),
|
|
190
|
+
loopMode: this.queue.loopMode,
|
|
191
|
+
length: this.queue.queue.length
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
toggleLoop() {
|
|
196
|
+
const modes = ['off', 'track', 'queue'];
|
|
197
|
+
const currentIndex = modes.indexOf(this.queue.loopMode);
|
|
198
|
+
const nextIndex = (currentIndex + 1) % modes.length;
|
|
199
|
+
this.queue.loopMode = modes[nextIndex];
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
success: true,
|
|
203
|
+
newMode: this.queue.loopMode
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
shuffle() {
|
|
208
|
+
if (this.queue.queue.length === 0) {
|
|
209
|
+
return {
|
|
210
|
+
success: false,
|
|
211
|
+
error: 'Queue is empty'
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
for (let i = this.queue.queue.length - 1; i > 0; i--) {
|
|
216
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
217
|
+
[this.queue.queue[i], this.queue.queue[j]] = [this.queue.queue[j], this.queue.queue[i]];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
success: true,
|
|
222
|
+
queue: this.getQueue()
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
isValidUrl(string) {
|
|
227
|
+
try {
|
|
228
|
+
new URL(string);
|
|
229
|
+
return true;
|
|
230
|
+
} catch (_) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
formatDuration(seconds) {
|
|
236
|
+
if (!seconds) return '0:00';
|
|
237
|
+
|
|
238
|
+
const hours = Math.floor(seconds / 3600);
|
|
239
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
240
|
+
const secondsRemaining = Math.floor(seconds % 60);
|
|
241
|
+
|
|
242
|
+
if (hours > 0) {
|
|
243
|
+
return `${hours}:${minutes.toString().padStart(2, '0')}:${secondsRemaining.toString().padStart(2, '0')}`;
|
|
244
|
+
}
|
|
245
|
+
return `${minutes}:${secondsRemaining.toString().padStart(2, '0')}`;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
startWebServer() {
|
|
249
|
+
try {
|
|
250
|
+
this.webServer = new IcecastServer({
|
|
251
|
+
port: this.config.serverPort,
|
|
252
|
+
publicStreamUrl: this.streamer.publicStreamUrl,
|
|
253
|
+
logger: this.bot.utils.logger
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
this.webServer.start();
|
|
257
|
+
return true;
|
|
258
|
+
} catch (error) {
|
|
259
|
+
console.error('Failed to start web server:', error);
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
destroy() {
|
|
265
|
+
try {
|
|
266
|
+
if (this.streamer) {
|
|
267
|
+
this.streamer.stop();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return true;
|
|
271
|
+
} catch (error) {
|
|
272
|
+
console.error('Error destroying music class:', error);
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
module.exports = MusicClass;
|