You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

615 lines
12 KiB

  1. let roles = require('../../config/roles');
  2. let generator = require('../../items/generator');
  3. let configSlots = require('../../items/config/slots');
  4. let configMaterials = require('../../items/config/materials');
  5. let factions = require('../../config/factions');
  6. let connections = require('../../security/connections');
  7. let commandRoles = {
  8. //Regular players
  9. join: 0,
  10. leave: 0,
  11. unEq: 0,
  12. roll: 0,
  13. block: 0,
  14. unblock: 0,
  15. //Mods
  16. mute: 5,
  17. unmute: 5,
  18. //Admin
  19. getItem: 10,
  20. getGold: 10,
  21. setLevel: 10,
  22. godMode: 10,
  23. clearInventory: 10,
  24. completeQuests: 10,
  25. getReputation: 10,
  26. loseReputation: 10,
  27. setStat: 10,
  28. die: 10,
  29. getXp: 10,
  30. setPassword: 10,
  31. giveSkin: 10,
  32. getMaterials: 10
  33. };
  34. let localCommands = [
  35. 'join',
  36. 'leave',
  37. 'mute',
  38. 'unmute',
  39. 'setPassword',
  40. 'roll',
  41. 'giveSkin',
  42. 'block',
  43. 'unblock'
  44. ];
  45. module.exports = {
  46. customChannels: [],
  47. roleLevel: null,
  48. init: function (blueprint) {
  49. if (this.customChannels) {
  50. this.customChannels = this.customChannels
  51. .filter((c, i) => (this.customChannels.indexOf(c) === i));
  52. }
  53. this.roleLevel = roles.getRoleLevel(this.obj);
  54. },
  55. onBeforeChat: function (msg) {
  56. let messageText = msg.message;
  57. if (messageText[0] !== '/')
  58. return;
  59. messageText = messageText.substr(1).split(' ');
  60. let actionName = messageText.splice(0, 1)[0].toLowerCase();
  61. actionName = Object.keys(commandRoles).find(a => (a.toLowerCase() === actionName));
  62. if (!actionName)
  63. return;
  64. else if (this.roleLevel < commandRoles[actionName])
  65. return;
  66. msg.ignore = true;
  67. let config = {};
  68. if ((messageText.length === 1) && (messageText[0].indexOf('=') === -1))
  69. config = messageText[0];
  70. else {
  71. messageText.forEach(function (m) {
  72. m = m.split('=');
  73. config[m[0]] = m[1];
  74. });
  75. }
  76. if (localCommands.indexOf(actionName) > -1)
  77. this[actionName](config);
  78. else {
  79. atlas.performAction(this.obj, {
  80. cpn: 'social',
  81. method: actionName,
  82. data: config
  83. });
  84. }
  85. },
  86. //actions
  87. join: async function (value) {
  88. if (typeof (value) !== 'string')
  89. return;
  90. value = value
  91. .trim()
  92. .split(' ').join('');
  93. let obj = this.obj;
  94. if (value.length === 0)
  95. return;
  96. else if (!value.match(/^[0-9a-zA-Z]+$/)) {
  97. obj.socket.emit('events', {
  98. onGetMessages: [{
  99. messages: [{
  100. class: 'color-redA',
  101. message: 'Channel names may only contain letters and numbers.',
  102. type: 'info'
  103. }]
  104. }]
  105. });
  106. return;
  107. } else if (value.length > 15) {
  108. obj.socket.emit('events', {
  109. onGetMessages: [{
  110. messages: [{
  111. class: 'color-redA',
  112. message: 'Channel names can not be longer than 15 characters.',
  113. type: 'info'
  114. }]
  115. }]
  116. });
  117. return;
  118. }
  119. let channels = obj.auth.customChannels;
  120. if (!channels.some(c => (c === value)))
  121. channels.push(value);
  122. else
  123. return;
  124. channels.push(value);
  125. let charname = obj.auth.charname;
  126. await io.setAsync({
  127. key: charname,
  128. table: 'customChannels',
  129. value: channels,
  130. serialize: true
  131. });
  132. obj.socket.emit('events', {
  133. onGetMessages: [{
  134. messages: [{
  135. class: 'color-yellowB',
  136. message: 'joined channel: ' + value,
  137. type: 'info'
  138. }]
  139. }]
  140. });
  141. obj.socket.emit('event', {
  142. event: 'onJoinChannel',
  143. data: value
  144. });
  145. },
  146. leave: async function (value) {
  147. if (typeof (value) !== 'string')
  148. return;
  149. let obj = this.obj;
  150. let channels = obj.auth.customChannels;
  151. if (!channels.some(c => (c === value))) {
  152. obj.socket.emit('events', {
  153. onGetMessages: [{
  154. messages: [{
  155. class: 'color-redA',
  156. message: 'you are not currently in that channel',
  157. type: 'info'
  158. }]
  159. }]
  160. });
  161. return;
  162. }
  163. channels.spliceWhere(c => (c === value));
  164. let charname = obj.auth.charname;
  165. await io.setAsync({
  166. key: charname,
  167. table: 'customChannels',
  168. value: channels,
  169. serialize: true
  170. });
  171. obj.socket.emit('event', {
  172. event: 'onLeaveChannel',
  173. data: value
  174. });
  175. this.obj.socket.emit('events', {
  176. onGetMessages: [{
  177. messages: [{
  178. class: 'color-yellowB',
  179. message: 'left channel: ' + value,
  180. type: 'info'
  181. }]
  182. }]
  183. });
  184. },
  185. block: function (target) {
  186. if (this.blockedPlayers.includes(target)) {
  187. this.sendMessage('That player has already been blocked', 'color-redA');
  188. return;
  189. }
  190. this.blockedPlayers.push(target);
  191. this.sendMessage(`Successfully blocked ${target}`, 'color-yellowB');
  192. this.updateMainThread('blockedPlayers', this.blockedPlayers);
  193. this.obj.socket.emit('event', {
  194. event: 'onGetBlockedPlayers',
  195. data: this.blockedPlayers
  196. });
  197. },
  198. unblock: function (target) {
  199. if (!this.blockedPlayers.includes(target)) {
  200. this.sendMessage('That player is not blocked', 'color-redA');
  201. return;
  202. }
  203. this.blockedPlayers.spliceWhere(f => f === target);
  204. this.sendMessage(`Successfully unblocked ${target}`, 'color-yellowB');
  205. this.updateMainThread('blockedPlayers', this.blockedPlayers);
  206. this.obj.socket.emit('event', {
  207. event: 'onGetBlockedPlayers',
  208. data: this.blockedPlayers
  209. });
  210. },
  211. isInChannel: function (character, channel) {
  212. return character.auth.customChannels.some(c => (c === channel));
  213. },
  214. roll: function () {
  215. let roll = 1 + ~~(Math.random() * 100);
  216. cons.emit('event', {
  217. event: 'onGetMessages',
  218. data: {
  219. messages: [{
  220. class: 'color-grayB',
  221. message: this.obj.name + ' rolled ' + roll,
  222. type: 'chat'
  223. }]
  224. }
  225. });
  226. },
  227. unEq: function () {
  228. let eq = this.obj.equipment;
  229. Object.keys(eq.eq).forEach(function (slot) {
  230. eq.unequip(eq.eq[slot]);
  231. });
  232. },
  233. mute: async function (target, reason = null) {
  234. if (typeof (target) === 'object') {
  235. let keys = Object.keys(target);
  236. target = keys[0];
  237. reason = keys[1] || null;
  238. }
  239. if (target === this.obj.name)
  240. return;
  241. let o = connections.players.find(f => (f.name === target));
  242. if (!o)
  243. return;
  244. let role = roles.getRoleLevel(o);
  245. if (role >= this.roleLevel)
  246. return;
  247. let social = o.social;
  248. if (social.muted) {
  249. this.sendMessage('That player has already been muted', 'color-redA');
  250. return;
  251. }
  252. let reasonMsg = '';
  253. if (reason)
  254. reasonMsg = ' (' + reason + ')';
  255. social.muted = true;
  256. this.sendMessage('Successfully muted ' + target, 'color-yellowB');
  257. this.sendMessage('You have been muted' + reasonMsg, 'color-yellowB', o);
  258. atlas.updateObject(o, {
  259. components: [{
  260. type: 'social',
  261. muted: true
  262. }]
  263. });
  264. await io.setAsync({
  265. key: new Date(),
  266. table: 'modLog',
  267. value: {
  268. source: this.obj.name,
  269. command: 'mute',
  270. target: target,
  271. reason: reason
  272. },
  273. serialize: true
  274. });
  275. },
  276. unmute: async function (target, reason = null) {
  277. if (typeof (target) === 'object') {
  278. let keys = Object.keys(target);
  279. target = keys[0];
  280. reason = keys[1] || null;
  281. }
  282. if (target === this.obj.name)
  283. return;
  284. let o = connections.players.find(f => (f.name === target));
  285. if (!o)
  286. return;
  287. let role = roles.getRoleLevel(o);
  288. if (role >= this.roleLevel)
  289. return;
  290. let social = o.social;
  291. if (!social.muted) {
  292. this.sendMessage('That player is not muted', 'color-redA');
  293. return;
  294. }
  295. let reasonMsg = '';
  296. if (reason)
  297. reasonMsg = ' (' + reason + ')';
  298. delete social.muted;
  299. this.sendMessage('Successfully unmuted ' + target, 'color-yellowB');
  300. this.sendMessage('You have been unmuted' + reasonMsg, 'color-yellowB', o);
  301. atlas.updateObject(o, {
  302. components: [{
  303. type: 'social',
  304. muted: null
  305. }]
  306. });
  307. await io.setAsync({
  308. key: new Date(),
  309. table: 'modLog',
  310. value: {
  311. source: this.obj.name,
  312. command: 'unmute',
  313. target: target,
  314. reason: reason
  315. },
  316. serialize: true
  317. });
  318. },
  319. clearInventory: function () {
  320. let inventory = this.obj.inventory;
  321. inventory.items
  322. .filter(i => !i.eq)
  323. .map(i => i.id)
  324. .forEach(i => inventory.destroyItem(i, null, true));
  325. },
  326. getItem: function (config) {
  327. if (config.slot === 'set') {
  328. configSlots.slots.forEach(function (s) {
  329. if (s === 'tool')
  330. return;
  331. let newConfig = extend({}, config, {
  332. slot: s
  333. });
  334. this.getItem(newConfig);
  335. }, this);
  336. return;
  337. }
  338. if (config.stats)
  339. config.stats = config.stats.split(',');
  340. if (config.name)
  341. config.name = config.name.split('_').join(' ');
  342. if (config.spellName)
  343. config.spellName = config.spellName.split('_').join(' ');
  344. if (config.type)
  345. config.type = config.type.split('_').join(' ');
  346. if (config.sprite)
  347. config.sprite = config.sprite.split('_');
  348. let spritesheet = config.spritesheet;
  349. delete config.spritesheet;
  350. let factionList = (config.factions || '').split(',');
  351. delete config.factions;
  352. let safe = config.safe;
  353. delete config.safe;
  354. let eq = config.eq;
  355. delete config.eq;
  356. let item = generator.generate(config);
  357. if (safe) {
  358. item.noDrop = true;
  359. item.noDestroy = true;
  360. item.noSalvage = true;
  361. }
  362. factionList.forEach(function (f) {
  363. if (f === '')
  364. return;
  365. let faction = factions.getFaction(f);
  366. faction.uniqueStat.generate(item);
  367. item.factions = [];
  368. item.factions.push({
  369. id: f,
  370. tier: 3
  371. });
  372. });
  373. if (spritesheet)
  374. item.spritesheet = spritesheet;
  375. let newItem = this.obj.inventory.getItem(item);
  376. if (eq)
  377. this.obj.equipment.equip(newItem.id);
  378. },
  379. getGold: function (amount) {
  380. let newGold = this.obj.trade.gold + ~~amount;
  381. newGold = Math.max(-1000000000, Math.min(1000000000, newGold));
  382. this.obj.trade.gold = newGold;
  383. this.obj.syncer.set(true, 'trade', 'gold', newGold);
  384. },
  385. setLevel: function (level) {
  386. let obj = this.obj;
  387. let syncer = obj.syncer;
  388. level = Math.max(1, ~~level);
  389. let stats = obj.stats;
  390. let values = stats.values;
  391. let oldLevel = values.level;
  392. values.level = level;
  393. let delta = level - oldLevel;
  394. values.hpMax += (40 * delta);
  395. syncer.setObject(true, 'stats', 'values', 'level', level);
  396. syncer.setObject(true, 'stats', 'values', 'hpMax', values.hpMax);
  397. process.send({
  398. method: 'object',
  399. serverId: obj.serverId,
  400. obj: {
  401. level: level
  402. }
  403. });
  404. stats.calcXpMax();
  405. },
  406. godMode: function () {
  407. let obj = this.obj;
  408. let statValues = obj.stats.values;
  409. let newValues = {
  410. int: 10000000,
  411. str: 10000000,
  412. dex: 10000000,
  413. hpMax: 10000000,
  414. hp: 10000000,
  415. manaMax: 10000000,
  416. mana: 10000000,
  417. sprintChance: 100,
  418. vit: 10000000
  419. };
  420. let syncer = obj.syncer;
  421. for (let s in newValues) {
  422. let newValue = newValues[s];
  423. statValues[s] = newValue;
  424. syncer.setObject(true, 'stats', 'values', s, newValue);
  425. }
  426. obj.spellbook.calcDps();
  427. },
  428. completeQuests: function () {
  429. let obj = this.obj;
  430. let quests = obj.quests;
  431. quests.quests.forEach(function (q) {
  432. q.isReady = true;
  433. q.complete();
  434. }, this);
  435. quests.quests = [];
  436. obj.instance.questBuilder.obtain(obj);
  437. },
  438. getReputation: function (faction) {
  439. if (typeof (faction) !== 'string')
  440. return;
  441. this.obj.reputation.getReputation(faction, 50000);
  442. },
  443. loseReputation: function (faction) {
  444. if (typeof (faction) !== 'string')
  445. return;
  446. this.obj.reputation.getReputation(faction, -50000);
  447. },
  448. setStat: function (config) {
  449. this.obj.stats.values[config.stat] = ~~config.value;
  450. },
  451. getXp: function (amount) {
  452. this.obj.stats.getXp(amount, this.obj, this.obj);
  453. },
  454. die: function () {
  455. this.obj.stats.takeDamage({
  456. amount: 99999
  457. }, 1, this.obj);
  458. },
  459. setPassword: async function (config) {
  460. let keys = Object.keys(config);
  461. let username = keys[0];
  462. let hashedPassword = keys[1];
  463. await io.setAsync({
  464. key: username,
  465. table: 'login',
  466. value: hashedPassword
  467. });
  468. },
  469. giveSkin: async function (config) {
  470. let keys = Object.keys(config);
  471. let username = keys[0];
  472. let skinId = keys[1];
  473. let skins = await io.getAsync({
  474. key: username,
  475. table: 'skins',
  476. isArray: true
  477. });
  478. skins.push(skinId);
  479. await io.setAsync({
  480. key: username,
  481. table: 'skins',
  482. value: skins,
  483. serialize: true
  484. });
  485. },
  486. getMaterials: function (config) {
  487. let inventory = this.obj.inventory;
  488. Object.entries(configMaterials).forEach(([material, blueprint]) => {
  489. inventory.getItem({
  490. name: material,
  491. quantity: config,
  492. material: true,
  493. ...blueprint
  494. });
  495. });
  496. }
  497. };