Advertisement
Guest User

Dewtube alv :v

a guest
May 21st, 2018
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.83 KB | None | 0 0
  1. "use strict";
  2.  
  3. const FS = require("../lib/fs.js");
  4.  
  5. // Cooldown per video (30 minutes)
  6. const RECORD_COOLDOWN = 5 * 60 * 1000;
  7.  
  8. // Drama Cooldown (1 hour)
  9. const DRAMA_COOLDOWN = 10 * 60 * 1000;
  10.  
  11. // Collaboration Cooldown (6 hours)
  12. const COLLAB_COOLDOWN = 30 * 60 * 1000;
  13.  
  14. let channels = FS("config/channels.json").readIfExistsSync();
  15.  
  16. if (channels !== "") {
  17. channels = JSON.parse(channels);
  18. } else {
  19. channels = {};
  20. }
  21.  
  22. function write() {
  23. FS("config/channels.json").writeUpdate(() => (
  24. JSON.stringify(channels)
  25. ));
  26. let data = "{\n";
  27. for (let u in channels) {
  28. data += '\t"' + u + '": ' + JSON.stringify(channels[u]) + ",\n";
  29. }
  30. data = data.substr(0, data.length - 2);
  31. data += "\n}";
  32. FS("config/channels.json").writeUpdate(() => (
  33. data
  34. ));
  35. }
  36.  
  37. function getChannel(user) {
  38. user = toId(user);
  39. let reply;
  40. for (let channel in channels) {
  41. if (channels[channel].owner === user) {
  42. reply = channels[channel].name;
  43. break;
  44. }
  45. }
  46. return reply;
  47. }
  48. getChannel = getChannel;
  49.  
  50. //Plugin Optimization
  51. let config = {
  52. version: "2.0.2.2",
  53. changes: ["Math changed for large & small creators", "Nerf Collabs", "Titles now affect your monetization chance", "Likes/Dislikes Ratio Math Re-done", "If dislikes are higher than your likes, DewTube demonetizes your video", "Collab Cooldown is now 6 hours", "Collabs now must be accepted", "Numbers now use commas appropriately", "Fix Collab Issues", "People will unsubscribe if they dislike your videos"],
  54. // Basic Filter for Instant Demonetization
  55. filter: ["nsfw", "porn", "sex", "shooting"],
  56. };
  57.  
  58. function collab(channel1, channel2) {
  59. channel1 = toId(channel1);
  60. channel2 = toId(channel2);
  61. let combinedSubs = channels[channel1].subscribers + channels[channel2].subscribers;
  62. let traffic = Math.floor(Math.random() * combinedSubs);
  63. if (traffic > 1000000) {
  64. // If the views will be over 1 million, half them so collaborations aren't entirely "broken"
  65. traffic = Math.round(traffic / 2);
  66. }
  67. return traffic;
  68. }
  69.  
  70. exports.commands = {
  71. dewtube: {
  72. info: function () {
  73. if (!this.runBroadcast()) return;
  74. let display = `<div style="padding: 20px 20px"><center><font size="5">DewTube</font></center><br /><center><font size="3">v${config.version}</font></center><br />`;
  75. if (config.changes) display += Chat.toListString(config.changes);
  76. display += `</div>`;
  77. return this.sendReplyBox(display);
  78. },
  79.  
  80. createchannel: "newchannel",
  81. create: "newchannel",
  82. makechannel: "newchannel",
  83. register: "newchannel",
  84. newchannel: function (target, room, user) {
  85. let [name, ...desc] = target.split(",").map(p => p.trim());
  86. if (!name || !desc) return this.parse(`/dewtubehelp`);
  87. if (name.length < 1 || name.length > 25) return this.errorReply(`Your channel name must be between 1-25 characters.`);
  88. if (desc.length < 1 || desc.length > 300) return this.errorReply(`Your channel description must be between 1-300 characters.`);
  89. if (channels[toId(name)]) return this.errorReply(`${name} already is a DewTube channel.`);
  90. if (getChannel(user.userid)) return this.errorReply(`You already have a DewTube channel.`);
  91. channels[toId(name)] = {
  92. id: toId(name),
  93. name: name,
  94. aboutme: desc,
  95. views: 0,
  96. videos: 0,
  97. subscribers: 0,
  98. owner: user.userid,
  99. vidProgress: "notStarted",
  100. lastRecorded: null,
  101. lastCollabed: null,
  102. creationDate: Date.now(),
  103. likes: 0,
  104. dislikes: 0,
  105. notifications: true,
  106. isMonetized: false,
  107. lastTitle: null,
  108. lastThumbnail: null,
  109. allowingDrama: false,
  110. lastDrama: null,
  111. strikes: 0,
  112. pendingCollab: null,
  113. };
  114. write();
  115. return this.sendReply(`You successfully created your DewTube channel "${name}"! To view your channel's stats, use /dewtube dashboard.`);
  116. },
  117.  
  118. deletechannel: "removechannel",
  119. delchannel: "removechannel",
  120. delete: "removechannel",
  121. terminatechannel: "removechannel",
  122. terminate: "removechannel",
  123. removechannel: function (target, room, user) {
  124. target = toId(target);
  125. if (!this.can("ban") && channels[target].owner !== user.userid) return this.errorReply(`You must be the channel owner or a Global Moderator (or higher) to delete a channel.`);
  126. if (!target || !channels[target]) return this.errorReply(`The channel "${target}" appears to not exist.`);
  127. delete channels[target];
  128. write();
  129. this.room.modlog(`${user.name} terminated the channel "${target}".`);
  130. return this.sendReply(`Channel "${target}" has been deleted.`);
  131. },
  132.  
  133. channelpage: "dashboard",
  134. channel: "dashboard",
  135. dashboard: function (target, room, user) {
  136. if (!this.runBroadcast()) return;
  137. if (!target) target = toId(getChannel(user.userid));
  138. let channelId = toId(target);
  139. if (!channels[channelId]) return this.errorReply(`This is not a DewTube channel.`);
  140. let vidProgress = channels[channelId].vidProgress;
  141. let display = `<center><h2>${channels[channelId].name}</h2><strong>Creator:</strong> ${gold-users.nameColor(channels[channelId].owner, true, true)}`;
  142. if (channels[channelId].isMonetized) display += ` <strong>(Approved Partner [&#9745;])</strong>`;
  143. display += `<br />`;
  144. if (channels[channelId].aboutme) display += `<strong>About Me:</strong> ${channels[channelId].aboutme}<br />`;
  145. if (channels[channelId].creationDate) display += `<strong>Created:</strong> ${new Date(channels[channelId].creationDate)}<br />`;
  146. if (channels[channelId].views > 0) display += `<strong>View Count:</strong> ${channels[channelId].views.toLocaleString()}<br />`;
  147. if (channels[channelId].subscribers > 0) display += `<strong>Subscriber Count:</strong> ${channels[channelId].subscribers.toLocaleString()}<br />`;
  148. if (channels[channelId].likes > 0) display += `<strong>Like Count:</strong> ${channels[channelId].likes.toLocaleString()}<br />`;
  149. if (channels[channelId].dislikes > 0) display += `<strong>Dislike Count:</strong> ${channels[channelId].dislikes.toLocaleString()}<br />`;
  150. if (channels[channelId].lastTitle && vidProgress === "notStarted") display += `<strong>Last Video:</strong> ${channels[channelId].lastTitle}<br />`;
  151. if (channels[channelId].lastThumbnail && vidProgress === "notStarted") display += `<strong>Last Video Thumbnail:</strong><br /> <img src="${channels[channelId].lastThumbnail}" width="250" height="140"><br />`;
  152. if (channels[channelId].videos > 0) display += `<strong>Total Videos Uploaded:</strong> ${channels[channelId].videos.toLocaleString()}<br />`;
  153. if (channels[channelId].allowingDrama) display += `<small><strong>(Allowing Drama: [&#9745;])</strong></small>`;
  154. display += `</center>`;
  155. return this.sendReplyBox(display);
  156. },
  157.  
  158. aboutme: "desc",
  159. description: "desc",
  160. desc: function (target, room, user) {
  161. let channelId = toId(getChannel(user.userid));
  162. if (!channels[channelId]) return this.errorReply(`You do not currently own a DewTube channel.`);
  163. if (!target || target.length > 300) return this.errorReply("Needs a target; no more than 300 characters.");
  164. channels[channelId].aboutme = target;
  165. write();
  166. return this.sendReplyBox(`Your channel description is now set to: <br /> ${channels[channelId].aboutme}.`);
  167. },
  168.  
  169. channellist: "discover",
  170. listchannels: "discover",
  171. channelslist: "discover",
  172. channels: "discover",
  173. socialblade: "discover",
  174. list: "discover",
  175. discover: function () {
  176. if (!this.runBroadcast()) return;
  177. if (Object.keys(channels).length < 1) return this.errorReply(`There are currently no DewTube channels in this gold-users.`);
  178. let output = `<div style="max-height: 200px; width: 100%; overflow: scroll;"><center><table border="1" cellspacing ="0" cellpadding="3"><tr><td>Channel Name</td><td>Description</td><td>Views</td><td>Subscribers</td><td>Likes</td><td>Dislikes</td><td>Dashboard</td><td>Owner</td></tr>`;
  179. let sortedChannels = Object.keys(channels).sort(function (a, b) {
  180. return channels[b].subscribers - channels[a].subscribers;
  181. });
  182. for (let channel = 0; channel < sortedChannels.length; channel++) {
  183. let curChannel = channels[sortedChannels[channel]];
  184. let aboutme = Chat.escapeHTML(curChannel.aboutme);
  185. if (aboutme.length > 100) aboutme = `${aboutme.substr(0, 100)}<br />${aboutme.substr(100)}`;
  186. output += `<tr>`;
  187. output += `<td>${Chat.escapeHTML(curChannel.name)}</td>`;
  188. output += `<td>${aboutme}</td>`;
  189. output += `<td>${curChannel.views.toLocaleString()}</td>`;
  190. output += `<td>${curChannel.subscribers.toLocaleString()}</td>`;
  191. output += `<td>${curChannel.likes.toLocaleString()}</td>`;
  192. output += `<td>${curChannel.dislikes.toLocaleString()}</td>`;
  193. output += `<td><button name="send" value="/dewtube dashboard ${curChannel.name}">${curChannel.name}</button></td>`;
  194. output += `<td>${gold-users.nameColor(curChannel.owner, true, true)}</td>`;
  195. output += `</tr>`;
  196. }
  197. output += `</table></center></div>`;
  198. this.sendReplyBox(output);
  199. },
  200.  
  201. film: "record",
  202. rec: "record",
  203. record: function (target, room, user) {
  204. if (!getChannel(user.userid)) return this.errorReply(`You do not have a DewTube channel yet.`);
  205. let [title, ...thumbnail] = target.split(",").map(p => p.trim());
  206. if (!title) return this.errorReply(`Please title the video you are filming.`);
  207. let channelId = toId(getChannel(user.userid));
  208. if (Date.now() - channels[channelId].lastRecorded < RECORD_COOLDOWN) return this.errorReply(`You are on record cooldown.`);
  209. let videoProgress = channels[channelId].vidProgress;
  210. if (videoProgress !== "notStarted") return this.errorReply(`You already have a video recorded.`);
  211. channels[channelId].vidProgress = "recorded";
  212. channels[channelId].lastTitle = title;
  213. channels[channelId].lastThumbnail = thumbnail;
  214. // Filter if the title is deemed "inappropriate"
  215. for (let badWord of config.filter) {
  216. // This is basically so we can standardize and check titles more efficiently as IDs would remove spaces etc
  217. let lowercaseTitle = target.toLowerCase();
  218. // Go ahead and warn them :^)
  219. if (lowercaseTitle.includes(badWord)) this.sendReply(`Your title "${target}" doesn't seem very ad-friendly to our sponsors.`);
  220. }
  221. write();
  222. this.sendReplyBox(`You have recorded a video titled "${title}"! Time to edit it! <button class="button" name="send" value="/dewtube edit">Edit it!</button><button class="button" name="send" value="/dewtube publish">Upload as-is!</button>`);
  223. },
  224.  
  225. editvideo: "edit",
  226. edit: function (target, room, user) {
  227. if (!getChannel(user.userid)) return this.errorReply(`You do not have a DewTube channel yet.`);
  228. let channelId = toId(getChannel(user.userid));
  229. let videoProgress = channels[channelId].vidProgress;
  230. if (videoProgress !== "recorded") return this.errorReply(`You haven't recorded any new footage yet.`);
  231. channels[channelId].vidProgress = "edited";
  232. write();
  233. return this.sendReplyBox(`Almost done! Now its time to upload ${channels[channelId].lastTitle}! <button class="button" name="send" value="/dewtube publish">Publish the Video!</button>`);
  234. },
  235.  
  236. pub: "publish",
  237. upload: "publish",
  238. publish: function (target, room, user) {
  239. if (!getChannel(user.userid)) return this.errorReply(`You do not have a DewTube channel yet.`);
  240. let channelId = toId(getChannel(user.userid));
  241. let videoProgress = channels[channelId].vidProgress;
  242. if (videoProgress === "notStarted") return this.errorReply(`Please record a video before uploading.`);
  243. let subCount = channels[channelId].subscribers;
  244. channels[channelId].lastRecorded = Date.now();
  245. channels[channelId].videos++;
  246. let title = channels[channelId].lastTitle;
  247. let generateEditedViews = Math.floor(Math.random() * subCount);
  248. let generateRawViews = Math.floor(Math.random() * Math.round(subCount / 100));
  249. // Factor in Sub Count conditions to support starting DewTubers (it's rough starting out)
  250. if (subCount === 0) {
  251. generateEditedViews = 10;
  252. generateRawViews = 5;
  253. } else if (subCount > 0 && subCount < 1000) {
  254. // Multiply views by 1.5x if they have less than 1,000 subscribers
  255. generateEditedViews = Math.round(generateEditedViews * 1.5);
  256. generateRawViews = Math.round(generateRawViews * 1.5);
  257. } else if (subCount > 1000 && subCount < 100000) {
  258. // Factor in inactive subscribers
  259. let inactivity = Math.floor(Math.random() * 10);
  260. generateEditedViews = Math.round(generateEditedViews / inactivity);
  261. generateRawViews = Math.round(generateRawViews / inactivity);
  262. } else if (subCount > 100000) {
  263. // Factor in inactive subscribers
  264. let inactivity = Math.floor(Math.random() * 100);
  265. generateEditedViews = Math.round(generateEditedViews / inactivity);
  266. generateRawViews = Math.round(generateRawViews / inactivity);
  267. }
  268. if (videoProgress === "edited" && generateEditedViews < 1) {
  269. generateEditedViews = 1;
  270. } else if (videoProgress === "recorded" && generateRawViews < 1) {
  271. generateRawViews = 1;
  272. }
  273. let loveHateRatio = Math.floor(Math.random() * 100);
  274. let generateEditedSubs;
  275. let generateEditedUnsubs;
  276. let generateEditedLikes;
  277. let generateEditedDislikes;
  278. let generateRawSubs;
  279. let generateRawUnsubs;
  280. let generateRawLikes;
  281. let generateRawDislikes;
  282. // 70% chance to have positive feedback; 30% chance for negative feedback
  283. if (loveHateRatio >= 70) {
  284. // More dislikes than like scenario
  285. generateEditedUnsubs = Math.floor(Math.random() * generateEditedViews);
  286. generateEditedSubs = Math.floor(Math.random() * generateEditedUnsubs);
  287. generateEditedDislikes = Math.floor(Math.random() * generateEditedViews);
  288. generateEditedLikes = Math.floor(Math.random() * generateEditedDislikes);
  289. generateRawUnsubs = Math.floor(Math.random() * generateRawViews);
  290. generateRawSubs = Math.floor(Math.random() * generateRawUnsubs);
  291. generateRawDislikes = Math.floor(Math.random() * generateRawViews);
  292. generateRawLikes = Math.floor(Math.random() * generateRawDislikes);
  293. } else {
  294. // More likes than dislikes scenario
  295. generateEditedSubs = Math.floor(Math.random() * generateEditedViews);
  296. generateEditedUnsubs = Math.floor(Math.random() * generateEditedSubs);
  297. generateEditedLikes = Math.floor(Math.random() * generateEditedViews);
  298. generateEditedDislikes = Math.floor(Math.random() * generateEditedLikes);
  299. generateRawSubs = Math.floor(Math.random() * generateRawViews);
  300. generateRawUnsubs = Math.floor(Math.random() * generateRawSubs);
  301. generateRawLikes = Math.floor(Math.random() * generateRawViews);
  302. generateRawDislikes = Math.floor(Math.random() * generateRawLikes);
  303. }
  304. if (generateEditedLikes + generateEditedDislikes > generateEditedViews) {
  305. generateEditedLikes = Math.round(generateEditedLikes / 2);
  306. generateEditedDislikes = Math.round(generateEditedDislikes / 2);
  307. }
  308. if (generateRawLikes + generateRawDislikes > generateRawViews) {
  309. generateRawLikes = Math.round(generateRawLikes / 2);
  310. generateRawDislikes = Math.round(generateRawDislikes / 2);
  311. }
  312. if (generateEditedSubs + generateEditedUnsubs > generateEditedViews) {
  313. generateEditedSubs = Math.round(generateEditedSubs / 2);
  314. generateEditedUnsubs = Math.round(generateEditedUnsubs / 2);
  315. }
  316. if (generateRawSubs + generateRawUnsubs > generateRawViews) {
  317. generateRawSubs = Math.round(generateRawSubs / 2);
  318. generateRawUnsubs = Math.round(generateRawUnsubs / 2);
  319. }
  320. if (generateEditedSubs < 1) generateEditedSubs = 1;
  321. if (generateRawSubs < 1) generateRawSubs = 1;
  322. if (videoProgress === "edited") {
  323. let positiveSubs = generateEditedSubs + channels[channelId].subscribers;
  324. let newViewCount = channels[channelId].views + generateEditedViews;
  325. let newLikeCount = channels[channelId].likes + generateEditedLikes;
  326. let newDislikeCount = channels[channelId].dislikes + generateEditedDislikes;
  327. channels[channelId].subscribers = positiveSubs;
  328. channels[channelId].views = newViewCount;
  329. channels[channelId].likes = newLikeCount;
  330. channels[channelId].dislikes = newDislikeCount;
  331. this.sendReplyBox(`Congratulations, your video titled "${title}" has received ${generateEditedViews.toLocaleString()} view${Chat.plural(generateEditedViews)}. ${generateEditedSubs.toLocaleString()} ${generateEditedSubs === 1 ? "person has" : "people have"} subscribed to your channel after seeing this video. You got ${generateEditedLikes.toLocaleString()} like${Chat.plural(generateEditedLikes)} and ${generateEditedDislikes.toLocaleString()} dislike${Chat.plural(generateEditedDislikes)}.<br /> Total Sub Count: ${positiveSubs.toLocaleString()}. Total View Count: ${newViewCount.toLocaleString()}. Total Likes: ${newLikeCount.toLocaleString()}. Total Dislikes: ${newDislikeCount.toLocaleString()}.`);
  332. } else {
  333. let positiveSubs = generateRawSubs + channels[channelId].subscribers;
  334. let newViewCount = channels[channelId].views + generateRawViews;
  335. let newLikeCount = channels[channelId].likes + generateRawLikes;
  336. let newDislikeCount = channels[channelId].dislikes + generateRawDislikes;
  337. channels[channelId].subscribers = positiveSubs;
  338. channels[channelId].views = newViewCount;
  339. channels[channelId].likes = newLikeCount;
  340. channels[channelId].dislikes = newDislikeCount;
  341. this.sendReplyBox(`Your un-edited video titled "${title}" has received ${generateRawViews.toLocaleString()} view${Chat.plural(generateRawViews)}. ${generateRawSubs.toLocaleString()} ${generateRawSubs === 1 ? "person has" : "people have"} subscribed to your channel after seeing this video. You got ${generateRawLikes.toLocaleString()} like${Chat.plural(generateRawLikes)} and ${generateRawDislikes.toLocaleString()} dislike${Chat.plural(generateRawDislikes)}.<br /> Total Sub Count: ${positiveSubs.toLocaleString()}. Total View Count: ${newViewCount.toLocaleString()}. Total Likes: ${newLikeCount.toLocaleString()}. Total Dislikes: ${newDislikeCount.toLocaleString()}.`);
  342. }
  343. if (channels[channelId].isMonetized) {
  344. let demonetization = Math.floor(Math.random() * 100);
  345. // Sorry that video seems un-friendly to the advertisers :^)
  346. for (let badWords of config.filter) {
  347. // This is basically so we can standardize and check titles more efficiently as IDs would remove spaces etc
  348. let lowercaseTitle = title.toLowerCase();
  349. if (lowercaseTitle.includes(badWords)) demonetization = 90;
  350. }
  351. // If the demonetization number or more dislikes were given than likes then DewTube demonetizes the user
  352. if (demonetization >= 70 || loveHateRatio >= 70) {
  353. this.sendReplyBox(`<i>Due to your video's failure to meet community guidelines it was not approved for monetization, therefore your video has been D E M O N E T I Z E D.</i>`);
  354. } else {
  355. let adRevenue = 0;
  356. if (videoProgress === "recorded") {
  357. adRevenue = Math.round(generateRawViews / 20);
  358. }
  359. if (videoProgress === "edited") {
  360. adRevenue = Math.round(generateEditedViews / 100);
  361. }
  362. if (adRevenue < 1) adRevenue = 1;
  363. if (adRevenue > 20) adRevenue = 20;
  364. Economy.writeMoney(user.userid, adRevenue);
  365. Economy.logTransaction(`${user.name} has got ${adRevenue} ${moneyName}${Chat.plural(adRevenue)} from posting a video.`);
  366. this.sendReplyBox(`<i>Your video meets community guidelines and was approved for monetization. You have profited ${adRevenue} ${moneyName}${Chat.plural(adRevenue)}!</i>`);
  367. }
  368. }
  369. // Restart video progress
  370. channels[channelId].vidProgress = "notStarted";
  371. write();
  372. if (channels[channelId].notifications) {
  373. let notification = Date.now() - channels[channelId].lastRecorded + RECORD_COOLDOWN;
  374. setTimeout(() => {
  375. if (Users.get(user.userid)) {
  376. user.send(`|pm|~DewTube Manager|~|Hey ${user.name}, just wanted to let you know you can upload again!`);
  377. }
  378. }, notification);
  379. }
  380. },
  381.  
  382. togglemonetization: "monetization",
  383. demonetize: "monetization",
  384. unmonetize: "monetization",
  385. monetize: "monetization",
  386. monetization: function (target, room, user) {
  387. let channelId = toId(getChannel(user.userid));
  388. if (!getChannel(user.userid)) return this.errorReply(`You do not have a DewTube channel yet.`);
  389. if (channels[channelId].subscribers < 1000) return this.errorReply(`Due to recent DewTube partnership guidelines you must have 1,000 subscribers to apply for monetization.`);
  390. if (channels[channelId].isMonetized) {
  391. channels[channelId].isMonetized = false;
  392. this.sendReply(`You have successfully deactivated monetization.`);
  393. } else {
  394. channels[channelId].isMonetized = true;
  395. this.sendReply(`You have successfully enabled monetization.`);
  396. }
  397. },
  398.  
  399. notifications: "notify",
  400. videonotifications: "notify",
  401. toggle: "notify",
  402. togglenotifications: "notify",
  403. notify: function (target, room, user) {
  404. if (!getChannel(user.userid)) return this.errorReply(`You do not have a DewTube channel yet.`);
  405. let channelId = toId(getChannel(user.userid));
  406. if (channels[channelId].notifications) {
  407. channels[channelId].notifications = false;
  408. this.sendReply(`You have successfully deactivated video notifications.`);
  409. } else {
  410. channels[channelId].notifications = true;
  411. this.sendReply(`You have successfully enabled video notifications.`);
  412. }
  413. },
  414.  
  415. dramaalert: "drama",
  416. expose: "drama",
  417. drama: function (target, room, user) {
  418. if (!getChannel(user.userid)) return this.errorReply(`You do not have a DewTube channel yet.`);
  419. if (!target) return this.errorReply(`Pick who you want to start drama with.`);
  420. let targetId = toId(target);
  421. let usersChannel = toId(getChannel(user.userid));
  422. if (!channels[targetId]) return this.errorReply(`"${target}" is not a channel.`);
  423. if (channels[targetId] === channels[usersChannel]) return this.errorReply(`You cannot have drama with yourself.`);
  424. if (!channels[targetId].allowingDrama) return this.errorReply(`${target} has disabled drama.`);
  425. if (channels[usersChannel].subscribers === 0 || channels[targetId].subscribers === 0) return this.errorReply(`Either yourself or the other DewTuber currently has zero subscribers.`);
  426. if (!channels[usersChannel].allowingDrama) return this.errorReply(`You must enable drama before starting drama.`);
  427. if (Date.now() - channels[usersChannel].lastDrama < DRAMA_COOLDOWN) return this.errorReply(`You are on drama cooldown.`);
  428. if (Date.now() - channels[targetId].lastDrama < DRAMA_COOLDOWN) return this.errorReply(`${target} is on drama cooldown.`);
  429. let badOutcomes = [`was exposed by ${target}.`, `was the victim of a Content Cop by ${target}.`, `was humiliated by ${target}.`, `was proven to have lied by ${target}.`, `was proven guilty by ${target}.`, `was caught faking content by ${target}.`];
  430. let goodOutcomes = [`won the debate against ${target}.`, `was favored by the community in an argument against ${target}.`, `proved they were innocent of ${target}'s accusations.`, `exposed ${target}.`];
  431. let determineOutcome = Math.floor(Math.random() * 2);
  432. let audience = channels[usersChannel].subscribers + channels[targetId].subscribers;
  433. let feedback = Math.floor(Math.random() * audience);
  434. let communityFeedback = Math.round(feedback / 2);
  435. if (communityFeedback < 1) communityFeedback = 1;
  436. let subChange = Math.round(communityFeedback / 10);
  437. if (subChange < 1) subChange = 1;
  438. channels[usersChannel].lastDrama = Date.now();
  439.  
  440. if (determineOutcome === 1) {
  441. let outcome = goodOutcomes[Math.floor(Math.random() * goodOutcomes.length)];
  442. let traffic = channels[usersChannel].views + communityFeedback;
  443. channels[usersChannel].views = traffic;
  444. let subscriberTraffic = channels[usersChannel].subscribers + subChange;
  445. channels[usersChannel].subscribers = subscriberTraffic;
  446. if (channels[targetId].subscribers < subChange) {
  447. channels[targetId].subscribers = 0;
  448. } else {
  449. let subscribers = channels[targetId].subscribers - subChange;
  450. channels[targetId].subscribers = subscribers;
  451. }
  452. if (Rooms("dewtube")) Rooms("dewtube").add(`|c|$DramaAlert|/raw ${gold-users.nameColor(user.name, true, true)}, also known as ${getChannel(user.userid)}, ${outcome}`).update();
  453. this.sendReply(`You have won the drama against ${target}. This resulted in you gaining ${subChange.toLocaleString()} subscribers. This lead to ${communityFeedback.toLocaleString()} view${Chat.plural(communityFeedback)} being trafficked to your channel.`);
  454. write();
  455. if (Users.get(channels[targetId].owner)) {
  456. Users(channels[targetId].owner).send(`|pm|${user.getIdentity()}|${channels[targetId].owner}|/raw ${gold-users.nameColor(user.name, true, true)} has been favored by the community in DewTube drama. This resulted in you losing ${subChange.toLocaleString()} subscriber${Chat.plural(subChange)}.`);
  457. }
  458. } else {
  459. let outcome = badOutcomes[Math.floor(Math.random() * badOutcomes.length)];
  460. if (channels[usersChannel].subscribers < subChange) {
  461. channels[usersChannel].subscribers = 0;
  462. } else {
  463. let subscribers = channels[usersChannel].subscribers - subChange;
  464. channels[usersChannel].subscribers = subscribers;
  465. }
  466. let traffic = channels[targetId].views + communityFeedback;
  467. channels[targetId].views = traffic;
  468. let subscriberTraffic = channels[targetId].subscribers + subChange;
  469. channels[targetId].subscribers = subscriberTraffic;
  470. if (Rooms("dewtube")) Rooms("dewtube").add(`|c|$DramaAlert|/raw ${gold-users.nameColor(user.name, true, true)}, also known as ${getChannel(user.userid)}, ${outcome}`).update();
  471. this.sendReply(`You have lost the drama against ${target}. This resulted in you losing ${subChange.toLocaleString()} subscriber${Chat.plural(subChange)}.`);
  472. write();
  473. if (Users.get(channels[targetId].owner)) {
  474. Users(channels[targetId].owner).send(`|pm|${user.getIdentity()}|${channels[targetId].owner}|/raw ${gold-users.nameColor(user.name, true, true)} has lost while trying to start drama with you. This resulted in you gaining ${subChange.toLocaleString()} subscriber${Chat.plural(subChange)}. You also trafficked ${communityFeedback.toLocaleString()} view${Chat.plural(communityFeedback)} from this drama.`);
  475. }
  476. }
  477. if (channels[usersChannel].notifications) {
  478. let notification = Date.now() - channels[usersChannel].lastDrama + DRAMA_COOLDOWN;
  479. setTimeout(() => {
  480. if (Users.get(user.userid)) {
  481. user.send(`|pm|~DewTube Manager|~|Hey ${user.name}, just wanted to let you know you can start drama again now!`);
  482. }
  483. }, notification);
  484. }
  485. },
  486.  
  487. disabledrama: "toggledrama",
  488. enabledrama: "toggledrama",
  489. toggledrama: function (target, room, user) {
  490. let channelId = toId(getChannel(user.userid));
  491. if (!channels[channelId]) return this.errorReply(`You do not currently own a DewTube channel.`);
  492. if (!channels[channelId].allowingDrama) {
  493. channels[channelId].allowingDrama = true;
  494. this.sendReply(`You have enabled having drama. This means you can start or be a target of drama. If you want to disable drama again /toggledrama again.`);
  495. } else {
  496. channels[channelId].allowingDrama = false;
  497. this.sendReply(`You have disabled having drama. This means you cannot start or be a target of drama. If you want to enable drama again /toggledrama again.`);
  498. }
  499. },
  500.  
  501. collab: "collaborate",
  502. collaborate: function (target, room, user) {
  503. if (!target) return this.parse(`/dewtubehelp`);
  504. let channelId = toId(getChannel(user.userid));
  505. if (!channels[channelId]) return this.errorReply(`You do not currently own a DewTube channel.`);
  506. let targetId = toId(target);
  507. if (!channels[targetId]) return this.errorReply(`"${target}" is not a channel.`);
  508. if (channels[targetId] === channels[channelId]) return this.errorReply(`You cannot collaborate with yourself (what would be the point?).`);
  509. // Check if the channel's owner is online (so the system can PM the user and avoid the chances the collaboration request will not be seen)
  510. if (!Users.get(channels[targetId].owner) || !Users.get(channels[targetId].owner).connected) return this.errorReply(`The owner of ${target} is not online.`);
  511. // Check if both user's are available to record a video and collab
  512. if (Date.now() - channels[channelId].lastCollabed < COLLAB_COOLDOWN) return this.errorReply(`You are on collaboration cooldown.`);
  513. if (Date.now() - channels[targetId].lastCollabed < COLLAB_COOLDOWN) return this.errorReply(`${target} is on collaboration cooldown.`);
  514. if (Date.now() - channels[channelId].lastRecorded < RECORD_COOLDOWN) return this.errorReply(`You are on record cooldown.`);
  515. if (Date.now() - channels[targetId].lastRecorded < RECORD_COOLDOWN) return this.errorReply(`${target} is on record cooldown.`);
  516. if (channels[channelId].pendingCollab) return this.errorReply(`You already have a pending collaboration request.`);
  517. // Add a check to allow the collaboration if the user is the other channel's pending collaboration just have them accept it
  518. if (channels[targetId].pendingCollab !== "" && channels[targetId].pendingCollab === channels[channelId].id) {
  519. return this.parse(`/dewtube accept ${channels[targetId].id}`);
  520. }
  521. channels[channelId].pendingCollab = targetId;
  522. write();
  523. Users.get(channels[targetId].owner).send(`|pm|${user.getIdentity()}|~|/html has sent you a collaboration request.<br /><button name="send" value="/dewtube accept ${channels[channelId].id}">Click to accept</button> | <button name="send" value="/dewtube deny ${channels[channelId].id}">Click to decline</button>`);
  524. return this.sendReply(`You have sent ${target} a collaboration request.`);
  525. },
  526.  
  527. accept: "acceptcollab",
  528. collabaccept: "acceptcollab",
  529. acceptcollab: function (target, room, user) {
  530. if (!target) return this.parse(`/dewtubehelp`);
  531. let channelId = toId(getChannel(user.userid));
  532. if (!channels[channelId]) return this.errorReply(`You do not currently own a DewTube channel.`);
  533. let targetId = toId(target);
  534. if (!channels[targetId]) return this.errorReply(`"${target}" is not a channel.`);
  535. if (channels[targetId].pendingCollab !== channels[channelId].id) return this.errorReply(`${target} has not sent you a collaboration request, or it was cancelled.`);
  536. // Check if both user's are available to record a video and collab
  537. if (Date.now() - channels[channelId].lastCollabed < COLLAB_COOLDOWN) return this.errorReply(`You are on collaboration cooldown.`);
  538. if (Date.now() - channels[targetId].lastCollabed < COLLAB_COOLDOWN) return this.errorReply(`${target} is on collaboration cooldown.`);
  539. if (Date.now() - channels[channelId].lastRecorded < RECORD_COOLDOWN) return this.errorReply(`You are on record cooldown.`);
  540. if (Date.now() - channels[targetId].lastRecorded < RECORD_COOLDOWN) return this.errorReply(`${target} is on record cooldown.`);
  541. let traffic = collab(channelId, targetId);
  542. if (traffic < 1) traffic = 1;
  543. let loveHateRatio = Math.floor(Math.random() * 100);
  544. // Default to 1 like since there is always guaranteed at least 1 view (and we want to be nice for a change)
  545. let generateLikes = 1;
  546. let generateDislikes = 0;
  547. let subscriberTraffic;
  548. let unsubs;
  549. // 70% chance to have positive feedback; 30% chance for negative feedback
  550. if (loveHateRatio >= 70) {
  551. // More dislikes than like scenario
  552. generateDislikes = Math.floor(Math.random() * traffic);
  553. generateLikes = Math.floor(Math.random() * generateDislikes);
  554. unsubs = Math.floor(Math.random() * traffic);
  555. subscriberTraffic = Math.floor(Math.random() * generateDislikes);
  556. } else {
  557. // More likes than dislikes scenario
  558. generateLikes = Math.floor(Math.random() * traffic);
  559. generateDislikes = Math.floor(Math.random() * generateLikes);
  560. subscriberTraffic = Math.floor(Math.random() * traffic);
  561. unsubs = Math.floor(Math.random() * subscriberTraffic);
  562. }
  563. if (subscriberTraffic < 1) subscriberTraffic = 1;
  564. // If the subscriber gain is over 5,000 subscribers halve it (so collaborations aren't "broken")
  565. if (subscriberTraffic > 5000) Math.round(subscriberTraffic / 2);
  566. let userViewTraffic = channels[channelId].views + traffic;
  567. let userSubTraffic = channels[channelId].subscribers + subscriberTraffic;
  568. let userUnsubTraffic = channels[channelId].subscribers - unsubs;
  569. let userLikeTraffic = channels[channelId].likes + generateLikes;
  570. let userDislikeTraffic = channels[channelId].dislikes + generateDislikes;
  571. let collabViewTraffic = channels[targetId].views + traffic;
  572. let collabSubTraffic = channels[targetId].subscribers + traffic;
  573. let collabUnsubTraffic = channels[targetId].subscribers - unsubs;
  574. let collabLikeTraffic = channels[targetId].likes + generateLikes;
  575. let collabDislikeTraffic = channels[targetId].dislikes + generateDislikes;
  576. // Be nice and just make the video not have any unsubs :P
  577. if (userUnsubTraffic > channels[channelId].subscribers || collabUnsubTraffic > channels[targetId].subscribers) unsubs = 0;
  578. let userSubChange = userSubTraffic - userUnsubTraffic;
  579. let userSubs = channels[channelId].subscribers + userSubChange;
  580. let collabSubChange = collabSubTraffic - collabUnsubTraffic;
  581. let collabSubs = channels[targetId].subscribers + collabSubChange;
  582. // Now to actually add the calculations
  583. channels[channelId].views = userViewTraffic;
  584. channels[channelId].subscribers = userSubs;
  585. channels[channelId].likes = userLikeTraffic;
  586. channels[channelId].dislikes = userDislikeTraffic;
  587. channels[targetId].views = collabViewTraffic;
  588. channels[targetId].subscribers = collabSubs;
  589. channels[targetId].likes = collabLikeTraffic;
  590. channels[targetId].dislikes = collabDislikeTraffic;
  591. // Update timers and video counters/titles/etc
  592. channels[channelId].lastCollabed = Date.now();
  593. channels[channelId].lastRecorded = Date.now();
  594. channels[channelId].lastTitle = `Collab w/ ${channels[targetId].name}!`;
  595. channels[channelId].videos++;
  596. channels[targetId].lastCollabed = Date.now();
  597. channels[targetId].lastRecorded = Date.now();
  598. channels[targetId].lastTitle = `Collab w/ ${channels[channelId].name}!`;
  599. channels[targetId].videos++;
  600. // Later implement profile pictures and use the other DewTuber's profile picture as the thumbnail
  601. channels[channelId].lastThumbnail = null;
  602. channels[targetId].lastThumbnail = null;
  603. // Since the other channel has proposed the collab reset the request now it is complete
  604. channels[targetId].pendingCollab = null;
  605. write();
  606. // PM the other channel's owner that they accepted and tell them what their channel gained
  607. if (Users.get(channels[targetId].owner)) {
  608. Users(channels[targetId].owner).send(`|pm|${user.getIdentity()}|${channels[targetId].owner}|/raw ${gold-users.nameColor(user.name, true, true)} has accepted your collaboration request. This resulted in both of you gaining the following: ${traffic.toLocaleString()} ${traffic === 1 ? "view" : "views"}, ${subscriberTraffic.toLocaleString()} ${subscriberTraffic === 1 ? "subscriber" : "subscribers"}, you lost ${unsubs.toLocaleString()} ${unsubs === 1 ? "subscriber" : "subscribers"}, ${generateLikes.toLocaleString()} ${generateLikes === 1 ? "like" : "likes"}, and ${generateDislikes.toLocaleString()} ${generateDislikes === 1 ? "dislike" : "dislikes"}.`);
  609. }
  610. // If the user's have notifications on send collab cooldown alerts
  611. if (channels[channelId].notifications) {
  612. let notification = Date.now() - channels[channelId].lastCollabed + COLLAB_COOLDOWN;
  613. setTimeout(() => {
  614. if (Users.get(user.userid)) {
  615. user.send(`|pm|~DewTube Manager|~|Hey ${user.name}, just wanted to let you know you can collaborate with DewTubers again!`);
  616. }
  617. }, notification);
  618. }
  619. if (channels[targetId].notifications) {
  620. let notification = Date.now() - channels[targetId].lastCollabed + COLLAB_COOLDOWN;
  621. setTimeout(() => {
  622. if (Users.get(channels[targetId].owner)) {
  623. Users.get(channels[targetId].owner).send(`|pm|~DewTube Manager|~|Hey ${Users.get(channels[targetId].owner)}, just wanted to let you know you can collaborate with DewTubers again!`);
  624. }
  625. }, notification);
  626. }
  627. this.sendReply(`You accepted ${channels[targetId].name}'s collaboration request this resulted in both of you gaining the following: ${traffic.toLocaleString()} ${traffic === 1 ? "view" : "views"}, ${subscriberTraffic.toLocaleString()} ${subscriberTraffic === 1 ? "subscriber" : "subscribers"}, you lost ${unsubs.toLocaleString()} ${unsubs === 1 ? "subscriber" : "subscribers"}, ${generateLikes.toLocaleString()} ${generateLikes === 1 ? "like" : "likes"}, and ${generateDislikes.toLocaleString()} ${generateDislikes === 1 ? "dislike" : "dislikes"}.`);
  628. },
  629.  
  630. reject: "denycollab",
  631. rejectcollab: "denycollab",
  632. declinecollab: "denycollab",
  633. decline: "denycollab",
  634. deny: "denycollab",
  635. denycollab: function (target, room, user) {
  636. if (!target) return this.parse(`/dewtubehelp`);
  637. let channelId = toId(getChannel(user.userid));
  638. if (!channels[channelId]) return this.errorReply(`You do not currently own a DewTube channel.`);
  639. let targetId = toId(target);
  640. if (!channels[targetId]) return this.errorReply(`"${target}" is not a channel.`);
  641. if (channels[targetId].pendingCollab !== channels[channelId]) return this.errorReply(`${target} has not sent you a collaboration request, or it was cancelled.`);
  642. // Reset the channel that was declined's pending collab
  643. channels[targetId].pendingCollab = null;
  644. write();
  645. // Let the other channel know their collaboration request was declined
  646. if (Users.get(channels[targetId].owner)) {
  647. Users(channels[targetId].owner).send(`|pm|${user.getIdentity()}|${channels[targetId].owner}|/raw ${gold-users.nameColor(user.name, true, true)}, owner of ${channels[channelId].name}, has declined your collaboration request. Feel free to try collaborating with another DewTuber.`);
  648. }
  649. return this.sendReply(`You have rejected the collaboration request from ${channels[targetId].name}.`);
  650. },
  651.  
  652. endcollab: "cancelcollab",
  653. cancel: "cancelcollab",
  654. cancelcollab: function (target, room, user) {
  655. if (!target) return this.parse(`/dewtubehelp`);
  656. let channelId = toId(getChannel(user.userid));
  657. if (!channels[channelId]) return this.errorReply(`You do not currently own a DewTube channel.`);
  658. let targetId = toId(target);
  659. if (!channels[targetId]) return this.errorReply(`"${target}" is not a channel.`);
  660. if (channels[channelId].pendingCollab !== targetId) return this.errorReply(`${target} does not have a pending collaboration request from you.`);
  661. // Reset pending collab request to nothing
  662. channels[channelId].pendingCollab = null;
  663. write();
  664. return this.sendReply(`You have cancelled your collaboration request with ${channels[targetId].name}.`);
  665. },
  666.  
  667. "": "help",
  668. help: function () {
  669. this.parse("/dewtubehelp");
  670. },
  671. },
  672.  
  673. dewtubehelp: [
  674. `/dewtube create [name], [description] - Creates a DewTube channel.
  675. /dewtube delete [name] - Deletes a DewTube channel. If the channel is not yours, you must have Global Moderator or higher.
  676. /dewtube desc [description] - Edits your DewTube channel's about me.
  677. /dewtube record [title], [optional thumbnail link] - Films a DewTube video.
  678. /dewtube edit - Edits a DewTube video.
  679. /dewtube publish - Publishs a DewTube video.
  680. /dewtube collab [channel] - Requests to collaborate with the specified channel.
  681. /dewtube accept [channel] - Accepts a collaboration request from the specified channel.
  682. /dewtube deny [channel] - Declines a collaboration request from the specified channel.
  683. /dewtube cancel [channel] - Cancels a collaboration request that you sent the specified channel.
  684. /dewtube monetization - Toggles monetization on your DewTube videos. Must have 1,000 subscribers.
  685. /dewtube drama [channel name] - Starts drama against the other channel. Both parties must have drama enabled.
  686. /dewtube toggledrama - Toggles on/off starting/being a target of drama.
  687. /dewtube notify - Toggles on/off notifications for when your cooldowns are finished.
  688. /dewtube dashboard [channel name] - Shows the channel's dashboard; defaults to yourself.
  689. /dewtube info - Shows the DewTube version and recent changes.
  690. /dewtube discover - Shows all of the DewTube channels.
  691. /dewtube help - Displays this help command.`,
  692. ],
  693. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement